2009-11-18 3 views
43

Ich bin daran interessiert, eine CPU-Cache-Flush in Windows zu erzwingen (aus Benchmark-Gründen möchte ich emulieren Start ohne Daten im CPU-Cache), vorzugsweise eine grundlegende C-Implementierung oder Win32-Aufruf.Wie kann ich eine CPU-Cache-Flush in x86 Windows tun?

Gibt es eine bekannte Möglichkeit, dies mit einem Systemanruf oder sogar etwas so hinterhältig zu tun, wie sagen Sie eine große memcpy?

Intel i686-Plattform (P4 und höher ist auch in Ordnung).

Antwort

49

Glücklicherweise gibt mehr als einen Weg, um explizit die Caches zu leeren.

Der Befehl "wbinvd" schreibt geänderten Cache-Inhalt zurück und markiert die Caches leer. Es führt einen Buszyklus aus, um externe Cachespeicher ihre Daten zu löschen. Leider ist es eine privilegierte Anweisung. Wenn es jedoch möglich ist, das Testprogramm unter DOS auszuführen, ist dies der richtige Weg. Dies hat den Vorteil, den Cache-Footprint des "OS" sehr klein zu halten.

Zusätzlich gibt es den Befehl "invd", der die Caches ohne ungültig macht und sie zum Hauptspeicher zurückspült. Dies verletzt die Kohärenz von Hauptspeicher und Cache, also müssen Sie sich darum kümmern. Nicht wirklich empfehlenswert.

Für Benchmarks ist die einfachste Lösung wahrscheinlich das Kopieren eines großen Speicherblocks in eine Region, die mit WC (write combining) anstelle von WB markiert ist. Der Speicherabbildungsbereich der Grafikkarte ist ein guter Kandidat, oder Sie können einen Bereich als WC selbst über die MTRR-Register markieren.

können Sie einige Ressourcen finden etwa bei Test programs for measuring clock cycles and performance monitoring. kurze Routinen Benchmarking

+1

Ohh, ich stehe richtig, ordentlich Ich wusste nichts über diese Anweisung. – Falaina

+1

Die wbinvd-Anweisung dauert in der Größenordnung von 2000-5000 Taktzyklen! Die meisten Anweisungen dauern im Durchschnitt 2-5. – unixman83

7

Es gibt x86-Assembly-Anweisungen, die die CPU zwingen, bestimmte Cache-Zeilen zu löschen (wie CLFLUSH), aber sie sind ziemlich unklar. CLFLUSH spült insbesondere nur eine ausgewählte Adresse aus L1-Caches.

etwas so hinterhältig wie tun, sagen eine große memcopy?

Ja, dies ist der einfachste Ansatz und stellt sicher, dass die CPU alle Cache-Ebenen löscht. Schließen Sie einfach die Cache-Flushing-Zeit von Ihren Benchmakrs aus und Sie sollten eine gute Idee bekommen, wie Ihr Programm unter Cachedruck funktioniert.

+1

„wird dafür sorgen, dass die CPU spült alle Cache-Ebenen.“ Nicht wahr, wie ich schon sagte, moderne kommerzielle CPUs, besonders wenn sie von einem Betriebssystem abstrahiert werden, können (und haben wahrscheinlich) sehr komplizierte Cache-Strategien. – marr75

+4

Ich glaube, Sie verwechseln den CPU-Cache mit anderen Caches auf Betriebssystemebene. Das Betriebssystem hat grundsätzlich keine Mitsprache darüber, was die CPU zwischenspeichern oder nicht zwischenspeichern wird, da diese Entscheidungen so schnell erfolgen müssen, dass es keine Zeit für Kernelunterbrechungen oder ähnliches gibt. CPU-Cache ist rein in Silizium implementiert. – intgr

+1

Ein Kontextwechsel lässt in der Tat andere Prozesse laufen und dadurch den Cache verschmutzen. Dies ist jedoch ein normaler Teil des Betriebssystemverhaltens - es wird mit oder ohne Benchmark durchgeführt, daher ist es sinnvoll, dies in Ihre Timings aufzunehmen. – intgr

2

Es gibt leider keine Möglichkeit, den Cache explizit zu leeren. Ein paar Ihrer Optionen sind:

1.) Thrash den Cache durch einige sehr große Speicheroperationen zwischen Iterationen des Codes, den Sie Benchmarking.

2.) Aktivieren Sie Cache Disable in der x86 Control Registers und benchmarken Sie das. Dies wird wahrscheinlich auch den Befehls-Cache deaktivieren, was möglicherweise nicht das ist, was Sie wollen.

3.) Implementieren Sie den Teil Ihres Codes Ihr Benchmarking (wenn möglich) mit Non-Temporal instructions. Allerdings sind dies nur Hinweise an den Prozessor über den Cache, es ist immer noch frei zu tun, was es will.

1 ist wahrscheinlich die einfachste und für Ihre Zwecke ausreichend.

bearbeiten: Oops, ich stehe korrigiert gibt es eine Anweisung, die x86-Cache ungültig zu machen, finden Sie drhirsch Antwort

+1

Ihre Behauptung, dass es keine Anweisungen für das Leeren des Cache gibt, ist falsch. Und das Umschreiben einer Routine mit nicht-zeitlichen Anweisungen zum Benchmarking ist Unsinn. Wenn die Daten, die die Routine verwendet, in die Caches passen, würde sie während des Benchmarks viel langsamer laufen, was die Messungen wertlos macht. – hirschhornsalz

+0

Es gibt keine Möglichkeit, den Cache explizit aus Windows zu entfernen. Sie haben keinen direkten Zugriff auf die Hardware ... es gibt nicht-portable Assembly-Anweisungen, die das tun können. – marr75

+2

Sie können es einfach in Windows 95,98, ME tun. Und selbst für die modernen Windows-Varianten können Sie es mit einem Treiber in Ring 0 implementieren. – hirschhornsalz

Verwandte Themen