Frage

Dies ist Teil der cachegrind ausgegeben. Dieser Teil des Codes wurde 1224-mal ausgeführt. elmg1 ist ein Array von unsigned long der Größe 16 x 20 My Maschine L1-Cache-Größe ist 32 KB, Größe 64B Cachezeile und 8-Wege-teilassoziativen.

  1. for (i = 0; i <20; i ++) 78.336 2.448 2 50.184 1.224 0 0 0 0
  2. {
  3. telm01 = elmg1 [i]; 146.880 0 0 73.440 0 0 24.480 0 0
  4. telm31 = (telm01 << 3) ^ val1; 97.920 0 0 48.960 0 0 24.480 0 0
  5. telm21 = (telm01 << 2) ^ (val1 >> 1); 146.880 1.224 1 48.960 0 0 24.480 0 0
  6. telm11 = (telm01 << 1) ^ (val1 >> 2); 146.880 0 0 48.960 0 0 24.480 0 0
  7. }

A. Der Grund, warum ich es haben hier gesagt, ist, dass in der 3. Zeile innerhalb der for-Schleife, habe ich eine Reihe von I1 Misses sehen (ein L2-Mißerfolg als auch). Es ist etwas verwirrend und ich konnte nicht den Grund, warum wohl?

B. Ich versuche, (Zeit) einen Teil des Codes zu optimieren. Die oben ist nur ein kleiner Ausschnitt. Ich denke, in meinem Programmspeicherzugriff eine kostet mich eine Menge. Wie in dem obigen Beispiel elmg1 ist ein Array von 16 x 20 Größe des unsigned longs. Wenn ich versuche, es in Code zu verwenden, gibt es immer einige vermisst, und in meinem Programm treten diese Variablen viel. Irgendwelche Vorschläge?

C. Ich brauche zuzuordnen und (manchmal initialisieren) diese unsigned sehnt. Können Sie, welche sollte ich es vorziehen, calloc oder Array-Deklaration und dann explizite Initialisierung. Durch die Art und Weise wird es einen Unterschied in der Art und Weise Cache Greifen sie?

Danke.

War es hilfreich?

Lösung

Haben Sie versucht, die Schleife entrollen?

  1. Ich würde dir keine Sorgen über L1 jetzt vermisst. Auch ein L2-Mißerfolg von 1224 mal ist ok, die CPU die Werte in den Cache zu einem bestimmten Zeitpunkt zu laden haben.
  2. Wie viele Prozent der L2 verfehlt hat diesen Code Kosten im Vergleich zum Rest des Programms?
  3. Verwenden Sie calloc (), wenn die Array-Größe ist immer gleich und Sie Konstanten für die Größe, dann kann der Compiler die zero'ing des Arrays optimieren. Auch die einzige Sache, die die Cache-Zeilen Verbräuche bewirken würde, ist die Ausrichtung, nicht, wie es war initizliated.

bearbeiten. Die Zahl wo hart, so zu lesen und sie falsch das erste Mal gelesen

lässt stellen Sie sicher, ich lese die Zahlen rechts für Zeile 5:

Ir    146,880
I1mr  1,224
ILmr  1
Dr    48,960
D1mr  0
DLmr  0
Dw    24,480
D1mw  0
DLmw  0

Die L1-Cache ist in zwei 32kByte eines für Code I1 und einer der Daten D1 zwischenspeichert. IL & DL ist der L2 oder L3-Cache, die von beiden Daten und Befehlen gemeinsam genutzt wird.

Die große Anzahl von I1mr ist befehl Misses nicht Daten-Misses, bedeutet dies, dass der Schleifencode wird aus dem Befehlscache I1 ausgestoßen wird.

I1 Fehltreffer in Zeile 1, 5, die insgesamt 3672 3-mal 1224, so dass jedes Mal, wenn die Schleife ausgeführt wird, man bekommt 3 I1 Cache-Misses mit 64Byte Cachezeilen Das heißt, man Schleifencodegröße zwischen 128 bis 192 Bytes beträgt 3 abzudecken Cache-Zeilen. So jenes I1 Misses in Zeile 5 ist, weil das ist, wo die Schleife Code die letzte Cache-Zeile durchquert.

Ich empfehle KCachegrind mit würde die Ergebnisse von cachegrind für die Anzeige

Edit:. Mehr über Cache-Zeilen

Dieser Code Schleife sieht nicht wie es seinen Ruf 1.224 Mal wird sich selbst ist, so dass Mittel mehr Code, der diesen Code aus der I1-Cache drückt.

Ihre 32 KByte I1-Cache wird in 512 Cache-Zeilen aufgeteilt (64 Byte pro Stück). Die „8-Wege-teilassoziativen“ Teil bedeutet, dass jede Speicheradresse nur 8 von diesen 512 Cachespeicherzeilen abgebildet wird. Wenn das ganze Programm, das Sie Profil ein kontinuierlicher Block von 32 KByte Speicher ist, dann wäre alles fit in die I1-Cache und keinen würde ausgeworfen. Das ist mostlikely nicht der Fall, und es werden mehr als 8 64Byte Codeblocks für die gleichen acht Cache-Zeilen begnügen. Lassen Sie sich sagen, dass Ihr gesamtes Programm 1MByte von Code hat (dazu gehört Bibliotheken), dann wird jede Gruppe von 8 Cache-Zeilen etwa 32 (1 MB / 32 KByte) Teile des Codes für die gleichen acht Cache-Zeilen begnügen.

Lesen Sie diesen lwn.net Artikel für alle die blutigen Details über die CPU-Caches

Der Compiler kann nicht immer erkennen, welche Funktionen des Programms Hotspots werden (viele, viele Male genannt) und die codespots sein wird (das heißt Fehler-Handler-Code, der fast läuft nie). GCC hat Funktionsattribute warm / kalt die es Ihnen erlaubt zu kennzeichnen Funktionen wie warm / kalt, wird dies die Compiler Gruppe die heißen Funktionen zusammen in einem Block des Speichers ermöglicht eine bessere Cache-Nutzung zu erhalten (nicht HotCode aus dem Caches dh kaltem Code wird schieben).

Wie auch immer diese I1 Misses sind wirklich nicht wert, die Zeit zu befürchten.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top