2010-05-27 22 views
15

有時我遇到的代碼讀取的TSC指令爲rdtsc,但在前面調用cpuid「cpuid」在「rdtsc」之前

爲什麼需要致電cpuid?我意識到它可能與具有TSC值的不同內核有關,但當您依次調用這兩個指令時,會發生什麼?

回答

16

這是爲了防止亂序執行。見here的全部細節,下面的相關位:

奔騰Pro和奔騰II處理器支持亂序執行指令可以以另一種順序事先設定它們執行。如果沒有照顧,這可能是錯誤的來源。

爲了防止這種情況,程序員必須序列化指令隊列。這可以通過在RDTSC指令之前插入像CPUID指令這樣的序列化指令來完成。

5

兩個原因:

  • 作爲paxdiablo說,當CPU看到了CPUID操作碼它確保所有先前的指令被執行,那麼CPUID採取任何後續指令執行前。如果沒有這樣的指令,CPU執行管道可能會在你想要的指令之前執行TSC。
  • 很大一部分機器無法同步跨內核的TSC寄存器。在你想從a中讀取它的馬嘴 - 在http://msdn.microsoft.com/en-us/library/ee417693%28VS.85%29.aspx敲你自己。因此,在測量TSC讀數之間的間隔時,除非它們採用相同的核心,否則將引入一個有效的隨機但可能不變的(見下文)時間間隔 - 啓動後甚至可能很快就會有幾秒鐘(是秒) 。這有效地反映了BIOS在單核上運行了多長時間之後,再加上 - 如果您有任何討厭的省電選項 - 增加由於運行在不同頻率或再次關閉的內核造成的漂移。因此,如果您沒有確定將TSC寄存器的線程固定到同一個核心,那麼您需要構建某種跨核心增量表,並按順序知道每個TSC樣本的核心ID(由CPUID返回)以補償這一偏移。這是您可以在RDTSC旁看到CPUID的另一個原因,也是爲什麼使用較新的RDTSCP許多操作系統將核心ID號存儲到返回的額外TSC_AUX [31:0]數據中的原因。 (可從Core i7和Athlon 64 X2獲得,RDTSCP在所有方面都是更好的選擇 - 操作系統通常會爲您提供所提到的核心ID,原子化爲TSC讀取,可防止指令重新排序)。