2010-05-27 4 views
15

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

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

ответ

16

Это должно предотвратить выполнение нестандартного исполнения. См here полной информации, соответствующие немного ниже:

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

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

5

Две причины:

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