Frage

Manchmal begegne ich Code, der TSC mit rdtsc Anweisung liest, aber Anrufe cpuid Recht vor.

Warum ruft cpuid notwendig? Ich weiß, es kann etwas mit unterschiedlichen Kernen TSC Werten zu tun, aber was genau passiert, wenn Sie diese beiden Befehle nacheinander anrufen?

War es hilfreich?

Lösung

Es ist zu verhindern, Out-of-Order-Ausführung. Von einer Verbindung, die jetzt aus dem Web verschwunden ist (aber das war zufällig hier kopiert, bevor sie verschwunden), ist dieser Text aus einem Artikel mit dem Titel „Performance Monitoring“ von einem John Eckerdal:

Die Pentium Pro und Pentium II-Prozessoren unterstützen Out-of-Order-Ausführung Anweisungen in einer anderen Reihenfolge ausgeführt werden können, wie Sie sie programmiert. Dies kann eine Fehlerquelle sein, wenn nicht gesorgt.

diese die Programmierer zu verhindern, muss die die Befehlswarteschlange serialisiert. Dies kann durch Einfügen eines Serialisierungsbefehl wie CPUID-Befehl vor der RDTSC Anweisung erfolgen.

Andere Tipps

Zwei Gründe:

  • Wie paxdiablo sagt, wenn die CPU einen CPUID Opcode sieht es stellt sicher, dass alle vorherigen Befehle ausgeführt werden, dann wird der CPUID genommen, bevor irgendwelche nachfolgenden Befehle auszuführen. Ohne eine solche Anweisung kann die CPU Ausführungs-Pipeline TSC am Ende der Ausführung, bevor die Anweisung (en), die Sie Zeit möchten.
  • Ein erheblicher Anteil der Maschinen versagt das TSC-Register über Kern zu synchronisieren. In Sie wollen, es zu lesen, von a Pferdemaul - klopfen Sie sich aus unter http://msdn.microsoft.com/en-us/library/ee417693%28VS.85%29.aspx . Also, wenn ein Intervall zwischen TSC Lesungen zu messen, es sei denn, sie auf dem gleichen Kern getroffen sind, werden Sie ein effektiv zufällige, aber möglicherweise konstant (siehe unten) Intervall eingeführt - es kann leicht mehrere Sekunden (ja Sekunden) sogar bald nach dem Starten . Diese effektiv reflektiert, wie lange das BIOS wurde auf einem einzigen Kern laufen, bevor aus den anderen tretend, plus - wenn Sie noch irgendeine böse Energiesparoptionen auf - zunehmenden Drift durch Kerne mit unterschiedlichen Frequenzen laufen oder herunter wieder. Also, wenn Sie nicht die Threads lesen TSC-Register auf den gleichen Kern genagelt haben, dann müssen Sie eine Art von Cross-Core-Delta-Tabelle erstellen und kennen die Kern-ID von jeder TSC Probe, um (die von CPUID zurückgeführt wird) um dies zu kompensieren kompensieren. Das ist ein weiterer Grund, warum Sie CPUID neben RDTSC, und in der Tat ein Grund, warum mit neueren RDTSCP vielen Betriebssyteme sind die Speicherung Kern-ID-Nummern in die extra TSC_AUX sehen [31: 0] Daten zurückgegeben. (Erhältlich von Core i7 und Athlon 64 X2, RDTSCP ist eine viel bessere Option in jeder Hinsicht - das Betriebssystem normalerweise gibt Ihnen die Kern-ID wie erwähnt, atomar TSC lesen, und verhindert Anweisung Nachbestellung).

CPUID ist die Serialisierung, verhindert out-of-Order-Ausführung von RDTSC.

In diesen Tagen können Sie sicher LFENCE stattdessen verwenden. Es ist, als die Serialisierung auf dem Befehlsstrom dokumentiert (aber nicht speichert in dem Speicher) auf Intel-CPUs, und jetzt auch auf AMD nach dem Microcode-Update für Specter.

https: // hadibrais.wordpress.com/2018/05/14/the-significance-of-the-x86-lfence-instruction/ erklärt mehr über LFENCE.

Siehe auch https://www.intel.com/content/dam/www/public/us/en/documents/white-papers/ia-32-ia-64-benchmark -Code-execution-Paper.pdf für eine Art und Weise zu verwenden RDTSC P , die CPUID (oder LFENCE) aus dem zeitlichen Bereich hält:

LFENCE     ; (or CPUID) Don't start the timed region until everything above has executed
RDTSC           ; EDX:EAX = timestamp
mov  ebx, eax   ; low 32 bits of start time

   code under test

RDTSCP     ; built-in one way barrier stops it from running early
LFENCE     ; (or CPUID) still use a barrier after to prevent anything weird
sub  eax, ebx   ; low 32 bits of end-start

Siehe auch Get CPU Zykluszahl? für mehr über RDTSC Einsprüche, wie CONSTANT_TSC und NONSTOP_TSC .

Als Bonus RDTSCP gibt Ihnen eine Kern-ID. Sie könnten auch RDTSCP für die Startzeit verwenden, wenn Sie für die Kern Migration überprüfen möchten. Aber wenn Ihre CPU die constant_tsc Funktionen, alle Kerne in dem Paket sollten ihre TSCs synchronisiert haben, damit Sie in der Regel diese nicht auf modernen x86 benötigen.

Sie könnten den Kern ID von CPUID stattdessen bekommen, wie @ Tonys Antwort weist darauf hin.

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