Tengo el siguiente fragmento de código C++ (la parte C++ es la clase de generador de perfiles que se omite aquí), compilada con VS2010 (máquina Intel de 64 bits). El código simplemente multiplica una serie de flotadores (arr2
) con un escalar, y pone el resultado en otra matriz (arr1
):Cómo depende el rendimiento de los valores de datos subyacentes
int M = 150, N = 150;
int niter = 20000; // do many iterations to have a significant run-time
float *arr1 = (float *)calloc (M*N, sizeof(float));
float *arr2 = (float *)calloc (M*N, sizeof(float));
// Read data from file into arr2
float scale = float(6.6e-14);
// START_PROFILING
for (int iter = 0; iter < niter; ++iter) {
for (int n = 0; n < M*N; ++n) {
arr1[n] += scale * arr2[n];
}
}
// END_PROFILING
free(arr1);
free(arr2);
La lectura-de-archivo de pieza y perfilado (es decir, la medición en tiempo de ejecución) es omitido aquí por simplicidad. arr2
Cuando arr2
se inicializa en números aleatorios en el rango [0 1], el código se ejecuta aproximadamente 10 veces más rápido que en un caso donde arr2
se inicializa en una matriz dispersa en la que aproximadamente 2/3 de los valores son ceros . He jugado con las opciones del compilador /fp
y /O
, que cambiaron un poco el tiempo de ejecución, pero se mantuvo aproximadamente la proporción de 1:10.
- ¿Cómo es que el rendimiento depende de los valores reales? ¿Qué hace la CPU de manera diferente que hace que la ejecución de datos dispersos sea 10 veces más lenta?
- ¿Hay alguna manera de hacer que la "información lenta" corra más rápido, o cualquier optimización (por ejemplo, vectorizando el cálculo) tendrá el mismo efecto en ambas matrices (es decir, los "datos lentos" seguirán siendo más lentos que los "rápidos" datos")?
EDITAR
de código completo está aquí: https://gist.github.com/1676742, la línea de comandos para la compilación está en un comentario en test.cpp
.
Los archivos de datos son aquí:
¿Podrías proporcionar versiones completas y compilables de las dos pruebas para que podamos experimentar con ellas? – NPE
¿Podría ser que cuando pasa '0' a su flotador en su matriz dispersa, la conversión de' int' a 'float' introduce cierta sobrecarga? –
¿Solo actualizas los elementos que no son 0? Entonces, ¿puede ser que los ceros no estén en la memoria caché? – duedl0r