Esta pregunta tiene cuatro años y estoy un poco sorprendido de que nadie haya mencionado el ancho de banda de la memoria todavía. CPU-Z informa que mi máquina tiene PC3-10700 RAM. Que la RAM tiene un ancho de banda máximo (también conocido como tasa de transferencia, rendimiento, etc.) de 10700 MBytes/seg. La CPU en mi máquina es una CPU i5-2430M, con una frecuencia máxima de turbo de 3 GHz.
En teoría, con una CPU infinitamente rápido y mi memoria RAM, memcpy podría ir a 5300 Mbytes/seg, es decir, la mitad de 10700 memcpy porque tiene que leer y luego escribir en la memoria RAM. (Editar: Como v.oddou señaló, esta es una aproximación simplista).
Por otro lado, imagina que tenemos una RAM infinitamente rápida y una CPU realista, ¿qué podríamos lograr? Usemos mi CPU de 3 GHz como ejemplo. Si pudiera hacer una lectura de 32 bits y una de 32 bits, escribir cada ciclo, entonces podría transferir 3e9 * 4 = 12000 MBytes/seg. Esto parece fácilmente al alcance de una CPU moderna. Ya podemos ver que el código que se ejecuta en la CPU no es realmente el cuello de botella. Esta es una de las razones por las que las máquinas modernas tienen cachés de datos.
Podemos medir lo que realmente puede hacer la CPU mediante la evaluación comparativa de memcpy cuando sabemos que los datos están en la memoria caché. Hacer esto con precisión es complicado. Hice una aplicación simple que escribía números aleatorios en una matriz, los remecía a otra matriz y luego sumaba los datos copiados. Pasé por el código en el depurador para asegurarme de que el compilador inteligente no haya eliminado la copia. Alterar el tamaño de la matriz altera el rendimiento de la memoria caché: pequeñas matrices encajan en la memoria caché, y las grandes no tanto. Me dieron los siguientes resultados:
- 40 KByte matrices: 16000 Mbytes/seg
- 400 KByte matrices: 11000 Mbytes/seg
- 4000 matrices KByte: 3100 MBytes/seg
Obviamente, mi CPU puede leer y escribir más de 32 bits por ciclo, ya que 16000 es más que los 12000 que calculé teóricamente. Esto significa que la CPU es aún menos un cuello de botella de lo que pensaba. Utilicé Visual Studio 2005, y entrando en la implementación estándar de memcpy, puedo ver que usa la instrucción movqda en mi máquina. Supongo que esto puede leer y escribir 64 bits por ciclo.
El buen código hapalibashi publicado alcanza 4200 MBytes/seg en mi máquina, aproximadamente un 40% más rápido que la implementación VS 2005. Supongo que es más rápido porque usa la instrucción de captación previa para mejorar el rendimiento de la memoria caché.
En resumen, el código que se ejecuta en la CPU no es el cuello de botella y sintonizar ese código solo hará pequeñas mejoras.
¿Puedes escribir tu código para que la copia no sea necesaria en primer lugar? – Ron
Ron, no, no puedo :( – horseyguy
Si puede obtener el compilador de Intel, puede tener mejores posibilidades de que el optimizador se convierta en instrucciones de la CPU de vector –