Чтобы даже иметь надежду на повторяющиеся, детерминированные сроки на уровне, который дает RDTSC, вам нужно предпринять некоторые дополнительные шаги.Во-первых, RDTSC является , а не инструкцией сериализации, поэтому ее можно выполнять не по порядку, что обычно делает ее бессмысленной в фрагменте, подобном приведенному выше.
Обычно вы хотите использоватьинструкция сериализации, затем ваш RDTSC, затем соответствующий код, другая команда сериализации и вторая RDTSC.
Практически единственной инструкцией сериализации, доступной в режиме пользователя, является CPUID.Это, однако, добавляет еще одну незначительную проблему: для CPUID задокументировано, что CPUID требует различного количества времени для выполнения - первая пара выполнений может быть медленнее, чем другие.
Таким образом, нормальная последовательность синхронизации дляВаш код будет выглядеть примерно так:
XOR EAX, EAX
CPUID
XOR EAX, EAX
CPUID
XOR EAX, EAX
CPUID ; Intel says by the third execution, the timing will be stable.
RDTSC ; read the clock
push eax ; save the start time
push edx
mov ebx, 0x1E532 // Seed // execute test sequence
shl ebx, 3
add ebx, 0x0054E9
mov value, ebx
XOR EAX, EAX ; serialize
CPUID
rdtsc ; get end time
pop ecx ; get start time back
pop ebp
sub eax, ebp ; find end-start
sbb edx, ecx
Мы начинаем приближаться, но есть последний момент, с которым трудно справиться с использованием встроенного кода на большинстве компиляторов: также могут быть некоторые эффекты от пересечениякэшировать строки, поэтому вы обычно хотите, чтобы ваш код был выровнен по 16-байтовой (абзацной) границе.Любой порядочный ассемблер поддержит это, но встроенная сборка в компиляторе обычно не будет.
Сказав все это, я думаю, вы тратите свое время.Как вы можете догадаться, я провел довольно много времени на этом уровне, и я совершенно уверен, что вы слышали, что это просто миф.В действительности все последние процессоры x86 используют набор так называемых «регистров переименования».Короче говоря, это означает, что имя, которое вы используете для регистра, на самом деле не имеет большого значения - процессор имеет гораздо больший набор регистров (например, около 40 для Intel), который он использует для реальных операций, поэтомуустановка значения в EBX против EAX мало влияет на регистр, который ЦП действительно собирается использовать внутри.Любой из них может быть сопоставлен с любым регистром переименования, в зависимости главным образом от того, какие регистры переименования оказываются свободными при запуске этой последовательности команд.