CPUID выполняет сериализацию, предотвращая неправильное выполнение RDTSC.
В эти дни вы можете смело использовать LFENCE. Он задокументирован как сериализация в потоке команд (но не в памяти) на процессорах Intel, а теперь и на AMD после их обновления микрокода для Spectre.
https://hadibrais.wordpress.com/2018/05/14/the-significance-of-the-x86-lfence-instruction/ объясняет больше о LFENCE.
См. Также https://www.intel.com/content/dam/www/public/us/en/documents/white-papers/ia-32-ia-64-benchmark-code-execution-paper.pdf, чтобы узнать, как использовать RDTSC P , который удерживает CPUID (или LFENCE) вне временной области:
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
См. Также Получить счетчик циклов ЦП? для получения дополнительной информации о предупреждениях RDTSC, таких как constant_tsc и nonstop_tsc.
В качестве бонуса RDTSCP дает вам основной идентификатор. Вы также можете использовать RDTSCP для времени запуска, если хотите проверить миграцию ядра. Но если ваш процессор имеет функции constant_tsc
, все ядра в пакете должны синхронизироваться с TSC, так что на современном x86 это обычно не требуется.
Вместо этого вы можете получить идентификатор ядра из CPUID, как указывает ответ @ Tony.