Ich weiß nicht, wie Cache-Leistung auf einem sehr niedrigen Niveau zu optimieren, über Cachelinie Größe oder Assoziativität denken. Das kannst du nicht über Nacht lernen. Wenn man bedenkt, dass mein Programm auf vielen verschiedenen Systemen und Architekturen läuft, denke ich nicht, dass es sich auf jeden Fall lohnt. Aber dennoch, es gibt wahrscheinlich einige Schritte, die ich unternehmen kann, um Cache-Misses im Allgemeinen zu reduzieren.C++: Verbessern der Cache-Leistung in einem 3D-Array
Hier ist eine Beschreibung meines Problems:
I eine 3D-Anordnung von Zahlen aufweisen, wobei Werte an den Punkten im Raum darstellt, wie [x] [y] [z]. Jede Dimension hat die gleiche Größe, also ist es wie ein Würfel. Daraus muss ich ein weiteres 3D-Array machen, wobei jeder Wert in diesem neuen Array eine Funktion von 7 Parametern ist: der entsprechende Wert im ursprünglichen 3D-Array plus die 6 Indizes, die ihn im Raum "berühren". Ich mache mir vorerst keine Sorgen um die Kanten und Ecken des Würfels.
Hier ist, was ich in C++ bedeuten Code:
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);
}
}
aber es scheint, wie wenn LÄNGE groß genug ist, werde ich Tonnen von Cache-Misses, wenn ich die Parameter für process
bin holen. Gibt es eine cache-freundlichere Möglichkeit, dies zu tun, oder eine bessere Möglichkeit, meine Daten anders als ein 3D-Array zu repräsentieren?
Und wenn Sie die Zeit haben, diese zusätzlichen Fragen zu beantworten, muss ich den Wert von LÄNGE berücksichtigen? Wie ist es anders, ob LÄNGE 20 gegen 100 gegen 10000 ist. Würde ich auch etwas anderes tun müssen, wenn ich etwas anderes als Ganzzahlen verwende, wie etwa eine 64-Byte-Struktur?
@ ildjarn:
Sorry, ich glaube nicht, dass der Code, der die Arrays erzeugt ich vorbei bin in process3DArray
zählte. Aber wenn es so wäre, würde ich gerne wissen warum.
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);
}
Was bedeutet "Tonnen"? Wie viele hast du erwartet? –
Ich weiß es nicht wirklich. Ich würde wahrscheinlich einen Cache-Fehltreffer für posX, negX, posY und negY bekommen, aber vielleicht nicht für posZ und negZ, da diese eine bessere Lokalität haben. – newprogrammer
http://en.wikipedia.org/wiki/Loop_tiling – Anycorn