Вопрос

Иногда я столкнулся с кодом, который читает TSC с rdtsc инструкция, но звонки cpuid прямо перед.

Почему звонит cpuid необходимо? Я понимаю, что это может иметь что-то делать с различными сердечками, имеющими значения TSC, но что точно происходит, когда вы называете эти две инструкции в последовательности?

Это было полезно?

Решение

Это для предотвращения выполнения вне заказа. Из ссылки, которая теперь исчезла из Интернета (но которая была случайно скопирована здесь до того, как она исчезла), этот текст состоит из статьи, озаглавленного «Мониторинг производительности» одним Джоном Экердалом:

Процессоры Pentium Pro и Pentium II поддерживают инструкции по выполнению вне заказа, могут быть выполнены в другом порядке, поскольку вы их запрограммировали. Это может быть источником ошибок, если не позаботиться о.

Чтобы предотвратить это программист должен сериализовать очередь инструкции. Это можно сделать, вставляя инструкцию сериализации, как инструкция CPUID перед инструкцией RDTSC.

Другие советы

Две причины:

  • Как говорит Paxdiablo, когда процессор видит CPUID OPCode, он гарантирует, что все предыдущие инструкции выполняются, затем CPUID предпринимается, прежде чем любые последующие инструкции выполняются. Без такой инструкции проводной эксплуатационный трубопровод CPU может в конечном итоге выполнять TSC перед инструкцией (ыми), которые вы хотели бы считать время.
  • Значительная доля машин не может синхронизировать регистры TSC по сердечкам. В вы хотите прочитать это от а. рот лошади - выбить себя в http://msdn.microsoft.com/en-us/library/ee417693%28vs.85%29.aspx.. Отказ Итак, при измерении интервала между показаниями TSC, если они не сделаны в том же ядре, у вас будет эффективно случайная, но, возможно, постоянная (см. Ниже) Интервал, представленный - это может быть легко через несколько секунд (да секунды) даже вскоре после загрузки Отказ Это эффективно отражает, как долго BIOS работал в одном ядре, прежде чем отключить остальные, плюс - если у вас есть какие-либо неприятные варианты энергосбережения, увеличивая дрейф, вызванные ядрами, работающими на разных частотах или снова отключаются. Итак, если вы не прибили реестры чтения The Threads, к тому же ямуру, то вам нужно будет построить какую-то скрещенную дельта-таблицу и знать идентификатор ядра (который возвращается CPUID) каждого образца TSC в порядке компенсировать это смещение. Это еще одна причина, по которой вы можете увидеть CPUID рядом с RDTSC, и действительно причина, по которой с более новым RDTSCP многие OSES хранят номера идентификаторов ядра в дополнительные данные TSC_AUX [31: 0]. (Доступно из Core i7 и Athlon 64 x2, Rdtscp - это гораздо лучший вариант во всех отношениях - ОС обычно дает вам идентификатор основного идентификатора, как упомянутое, атомное для чтения TSC, а также Предотвратить заказание инструкций).

CPUID сериализация, предотвращая внесение выполнения RDTSC.

В эти дни вы можете безопасно использовать женс вместо этого. Он задокументирован как сериализация на потоке инструкций (но не хранит в памяти) на Intel CPU, а теперь также на AMD после их обновления микрокода для призрака.

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-excution-paper.pdf. Для использования RDTSCп который держит CPUID (или LFENGE) из-за того, что Именной области:

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

Смотрите также Получить CPU Cover Count? Для получения дополнительной информации о предостережениях RDTSC, таких как Constance_tsc и nonstop_tsc.

Как бонус, RDTSCP дает вам идентификатор ядра. Вы также можете использовать RDTSCP для времени начала, если вы хотите проверить наличие основной миграции. Но если ваш ЦП имеет constant_tsc Особенности, все ядра в пакете должны иметь синхронизм их TSS, чтобы вы, как правило, не нуждаетесь в этом на современном X86.

Вместо этого вы можете получить идентификатор основного идентификатора CPUID, так как @ Ответ Tony указывает.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top