Verwirrendes Caching-Verhalten eines einfachen C-Programms

8

Ich experimentiere mit einem Programm, um zu sehen, ob sein Caching-Verhalten mit meinem konzeptionellen Verständnis übereinstimmt.

Dazu benutze ich den Perf Befehl:

%Vor%

um das Cache-Miss-Verhältnis des folgenden einfachen C -Programms aufzuzeichnen:

%Vor%

Ich erhalte ein Cache-Miss-Verhältnis von 50.212%. Wenn ich das Array-Zugriffsmuster wie folgt ändere:

%Vor%

Ich bekomme, dass das Cache-Miss-Verhältnis 22.206% ist.

Diese Ergebnisse sind überraschend für mich.

  1. Das Cache-Miss-Verhältnis von 50,212% scheint sehr hoch für ein so einfaches Programm mit einem sehr regelmäßigen Speicherzugriffsmuster. Ich würde erwarten, dass dies näher bei 1 / (Anzahl Wörter pro Cache-Zeile) liegt, was definitiv größer als 1/2 ist. Warum ist das Cache-Miss-Verhältnis so hoch?
  2. Mein (begrenztes) Verständnis des Gedächtnisses legt nahe, dass das Iterieren über das Array in der Reihenfolge der Spaltenhäufigkeit zu einem viel schlechteren Caching-Verhalten führen sollte, aber die Ergebnisse, die ich erhalte, weisen auf das Gegenteil hin. Was ist los?
DzedCPT 14.12.2017, 11:34
quelle

1 Antwort

1

Die Antwort ist ziemlich einfach: Compiler optimieren Ihre Aufgaben. So sieht die Disassemblierung für Ihren Code aus:

%Vor%

Wie Sie sehen können, wurden für die Zeile arr[i * N + j] = 10.0; keine Assembler-Anweisungen generiert, so dass diese Cache-Misses, die Sie mit perf beobachten, nicht zusammenhängen.

Die Lösung ist ziemlich einfach. Fügen Sie einfach volatile zur Zeigerdeklaration hinzu und erzwingen Sie, dass der Compiler die Zuweisungen generiert, d. H .:

%Vor%

Die Demontage jetzt:

%Vor%

Und es gibt noch viel mehr Cache-Fehler.

Wenn Sie Ihren Test nur einmal ausführen, erhalten Sie möglicherweise sehr laute Ergebnisse. Sie sollten Ihre Messungen einige Male durchführen und einen Median nehmen. Es gibt Benchmark-Frameworks wie Google Benchmark. Sehen Sie sich das bitte an.

Und der letzte. Beide Ihrer Muster, wie i * N + j und j * N + i , sind vom CPU-Prefetcher leicht zu erkennen, daher sollte das Cache-Miss-Verhältnis in beiden Fällen ziemlich ähnlich sein ...

    
Andriy Berestovskyy 16.12.2017, 13:01
quelle

Tags und Links