C ++: Mejora del rendimiento de la memoria caché en una matriz 3d
No sé cómo optimizar el rendimiento de la caché a un nivel realmente bajo, pensando en el tamaño de la línea de caché o la asociatividad. Eso no es algo que puedas aprender de la noche a la mañana. Teniendo en cuenta que mi programa se ejecutará en muchos sistemas y arquitecturas diferentes, no creo que valga la pena de todos modos. Pero aún así, probablemente hay algunos pasos que puedo tomar para reducir las fallas de caché en general.
Aquí hay una descripción de mi problema:
Tengo una matriz 3D de enteros, que representan valores en puntos en el espacio, como [x] [y] [z]. Cada dimensión es del mismo tamaño, por lo que es como un cubo. A partir de eso, necesito hacer otra matriz 3D, donde cada valor en esta nueva matriz es una función de 7 parámetros: el valor correspondiente en la matriz 3D original, más los 6 índices que lo "tocan" en el espacio. No estoy preocupado por los bordes y las esquinas del cubo por ahora.
Aquí es lo que quiero decir en código C ++:
void process3DArray (int input[LENGTH][LENGTH][LENGTH],
int output[LENGTH][LENGTH][LENGTH])
{
for(int i = 1; i < LENGTH-1; i++)
for (int j = 1; j < LENGTH-1; j++)
for (int k = 1; k < LENGTH-1; k++)
//The for loops start at 1 and stop before LENGTH-1
//or other-wise I'll get out-of-bounds errors
//I'm not concerned with the edges and corners of the
//3d array "cube" at the moment.
{
int value = input[i][j][k];
//I am expecting crazy cache misses here:
int posX = input[i+1] [j] [k];
int negX = input[i-1] [j] [k];
int posY = input[i] [j+1] [k];
int negY = input[i] [j-1] [k];
int posZ = input[i] [j] [k+1];
int negZ = input[i] [j] [k-1];
output [i][j][k] =
process(value, posX, negX, posY, negY, posZ, negZ);
}
}
in embargo, parece que si LENGTH es lo suficientemente grande, obtendré toneladas de errores de caché cuando busque los parámetros paraprocess
. ¿Hay una forma más amigable de hacer esto para caché, o una mejor manera de representar mis datos que no sea una matriz 3D?
Y si tienes tiempo para responder estas preguntas adicionales, ¿tengo que considerar el valor de LENGTH? Como si fuera diferente si LENGTH es 20 vs 100 vs 10000. Además, ¿tendría que hacer algo más si usara algo diferente a los enteros, como quizás una estructura de 64 bytes?
@ ildjarn:
Lo siento, no pensé que el código que genera los arreglos que estoy pasando aprocess3DArray
importaba. Pero si es así, me gustaría saber por qué.
int main() {
int data[LENGTH][LENGTH][LENGTH];
for(int i = 0; i < LENGTH; i++)
for (int j = 0; j < LENGTH; j++)
for (int k = 0; k < LENGTH; k++)
data[i][j][k] = rand() * (i + j + k);
int result[LENGTH][LENGTH][LENGTH];
process3DArray(data, result);
}