Beim Lesen dieser beiden Fragen sehe ich, dass es wichtig sein kann, das Verhalten des CPU-Cachings zu verstehen, wenn große Datenmengen im Speicher verarbeitet werden. Ich möchte verstehen, wie das Zwischenspeichern funktioniert, um meiner Optimierungs-Toolbox ein weiteres Tool hinzuzufügen.
Was sind die Kernpunkte der Funktionsweise des CPU-Caches, damit ich Code schreiben kann, der ihn sinnvoll verwendet? Gibt es eine Möglichkeit, Code zu profilieren, um festzustellen, ob eine schlechte Cache-Nutzung die Geschwindigkeit beeinträchtigt?
c
optimization
caching
Timothy Jones
quelle
quelle
Antworten:
quelle
Die Komplexität dieses Themas war heutzutage für den Menschen unverständlich. (Das ist seit den letzten 5 Jahren so.) Kombinieren Sie dies mit der Kurzvektorparallelität (SIMD) und Sie haben das Gefühl, dass die Optimierung von Code von Hand nicht mehr wirtschaftlich machbar ist - nicht, dass es nicht möglich wäre, aber es wäre nicht mehr wirtschaftlich sein.
Der derzeitige Ansatz besteht darin, den Computern beizubringen, wie sie optimieren können - indem sie Codevarianten erstellen, die dieselben Antworten mit unterschiedlichen Strukturen (Schleifen, Datenstrukturen, Algorithmen) berechnen, und die Leistung automatisch bewerten. Die Regeln für Code-Transformationen werden mit einem sehr strengen mathematischen Modell spezifiziert, so dass sie sowohl von Informatikern als auch von Computern ausgeführt werden können.
Der folgende Link wurde von Larry OBrien in einer seiner Antworten gepostet .
http://onward-conference.org/2011/images/Pueschel_2011_AutomaticPerformanceProgramming_Onward11.pdf
quelle
Es ist durchaus möglich, Caches zu verstehen und zu optimieren. Es beginnt mit dem Verstehen der Hardware und setzt sich fort, die Kontrolle über das System zu behalten. Je weniger Kontrolle Sie über das System haben, desto unwahrscheinlicher ist es, dass Sie Erfolg haben. Linux oder Windows mit einer Reihe von Anwendungen / Threads, die nicht im Leerlauf sind.
Die meisten Caches haben ähnliche Eigenschaften. Verwenden Sie einen Teil des Adressfelds, um nach Treffern zu suchen. Sie haben eine Tiefe (Wege) und eine Breite (Cache-Zeile). Einige haben Schreibpuffer, andere können so konfiguriert werden, dass sie den Cache beim Schreiben durchlaufen oder umgehen, usw.
Sie müssen genau wissen, welche Speichertransaktionen in diesem Cache ablaufen (einige Systeme verfügen über unabhängige Befehls- und Datencaches, die die Aufgabe erleichtern).
Sie können einen Cache leicht unbrauchbar machen, indem Sie Ihren Speicher nicht sorgfältig verwalten. Wenn Sie beispielsweise mehrere Datenblöcke verarbeiten, in der Hoffnung, sie im Cache zu behalten, sie sich jedoch an Adressen im Speicher befinden, die sogar ein Vielfaches der Cachetreffer- / -fehlersuche betragen, z. B. 0x10000 0x20000 0x30000, und Sie haben mehr von Abgesehen von den Möglichkeiten im Cache kann es sehr schnell vorkommen, dass bei eingeschaltetem Cache etwas sehr Langsames entsteht, das langsamer ist als bei ausgeschaltetem Cache. Aber ändern Sie das auf vielleicht 0x10000, 0x21000, 0x32000 und das könnte ausreichen, um den Cache voll auszunutzen und die Räumungen zu reduzieren.
Fazit: Der Schlüssel zur Optimierung eines Caches (abgesehen von einer guten Systemkenntnis) besteht darin, alle erforderlichen Leistungsmerkmale gleichzeitig im Cache zu speichern und die Daten so zu organisieren, dass sie verfügbar sind alles auf einmal im Cache. Und verhindern, dass Dinge wie Codeausführung, Interrupts und andere regelmäßige oder zufällige Ereignisse signifikante Teile dieser Daten, die Sie verwenden, entfernen.
Gleiches gilt für Code. Es ist jedoch etwas schwieriger, da Sie die Speicherorte des Codes kontrollieren müssen, um Kollisionen mit anderem Code zu vermeiden, den Sie im Cache behalten möchten. Während Sie jeden Code testen / profilieren, der einen Cache durchläuft, in dem hier und da eine einzelne Codezeile oder sogar ein einzelnes NOP hinzugefügt wird, ändert sich alles, was die Adressen verschiebt oder ändert, an denen der Code von einer Kompilierung zur anderen für denselben Code vorhanden ist, an der Position Die Cache-Zeilen fallen in diesen Code und ändern, was entfernt wird und was nicht für kritische Abschnitte.
quelle
Beide nwong ist und Michael Borgwardt die Antworten geben gute Ratschläge.
Vertrauen Sie auch zuerst den Optimierungen des Compilers in diesen Punkten.
Wenn Sie einen neueren GCC-Compiler verwenden, können Sie dessen
__builtin_prefetch
Funktion (mit Sparsamkeit) verwenden. Sehen Sie diese Antwort auf Stackoverflow.quelle