Was ist bei der Optimierung für den CPU-Cache (in C) wichtig?


13

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?


Caches sind nicht überall gleich; am offensichtlichsten variieren sie in der Größe. Erwarten Sie keine tiefen Geheimnisse, nur gute Praktiken (wie der Rat von Michael Borgwardt).
David Thornley

Antworten:


17
  • Halten Sie Ihre Daten möglichst klein
  • Behalten Sie die Dinge, auf die gemeinsam (oder direkt nacheinander) zugegriffen wird, nebeneinander im Speicher
  • Erfahren Sie mehr über die Optimierungsparameter Ihres Compilers
  • Lesen Sie, was jeder Programmierer über Speicher wissen sollte, um mehr Details zu erfahren, als Sie sich jemals wünschen könnten

+1 für "Dinge, auf die zugegriffen werden soll, nebeneinander aufbewahren"; Das ist derjenige, den man leicht vergisst.
Donal Fellows

Und den Compiler anweisen, zu optimieren.
Rightfold

@WTP: Richtig - hinzugefügt.
Michael Borgwardt

Halten Sie auch Mutexe gut getrennt. Durch das Ändern eines Mutex werden alle Cache-Zeilen in allen CPUs geleert, in denen er sich befindet. Dies kann eine große Leistungseinbuße sein, wenn Sie es geschafft haben, 2-3 Mutexe in einer einzelnen Cache-Zeile zu erhalten.
Vatine

12

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


2
Die BLAS-Implementierung von Fasttest (GotoBLAS) verwendet handoptimierten Code, um die maximale
Cachenutzung

2

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.


Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.