VC+對(duì)內(nèi)聯(lián)程序集使用完全不同的語(yǔ)法-但只在32位版本中使用.64位編譯器根本不支持內(nèi)聯(lián)程序集。
在這種情況下,這很可能也是-rdtsc
當(dāng)涉及到定時(shí)代碼序列時(shí),(至少)有兩個(gè)主要問(wèn)題。首先(與大多數(shù)指令一樣)它可以按順序執(zhí)行,因此,如果您試圖安排一個(gè)簡(jiǎn)短的代碼序列,rdtsc
在該代碼之前和之后都可能執(zhí)行,或者在它之后執(zhí)行,或者您有什么內(nèi)容(我相當(dāng)肯定這兩個(gè)代碼將始終按照彼此的順序執(zhí)行,因此至少兩者之間的區(qū)別永遠(yuǎn)不會(huì)是否定的)。
其次,在多核(或多處理器)系統(tǒng)上,一個(gè)rdtsc可能在一個(gè)核心/處理器上執(zhí)行,另一個(gè)在另一個(gè)核心/處理器上執(zhí)行。在這種情況下,結(jié)果是否定的是完全有可能。
一般來(lái)說(shuō),如果您想要在Windows下有一個(gè)精確的定時(shí)器,最好使用QueryPerformanceCounter
.
如果你真的堅(jiān)持用rdtsc
,我相信您必須在一個(gè)完全用匯編語(yǔ)言編寫(xiě)的單獨(dú)模塊中完成(或者使用編譯器內(nèi)部的),然后與您的C或C+鏈接。我從未為64位模式編寫(xiě)過(guò)該代碼,但在32位模式下,它看起來(lái)如下所示:
xor eax, eax
cpuid
xor eax, eax
cpuid
xor eax, eax
cpuid
rdtsc ; save eax, edx ; code you're going to time goes here
xor eax, eax
cpuid
rdtsc
我知道這看起來(lái)很奇怪,但實(shí)際上是對(duì)的。執(zhí)行CPUID是因?yàn)樗且粋€(gè)序列化指令(不能按順序執(zhí)行),并且可以在用戶模式下使用。在開(kāi)始計(jì)時(shí)之前執(zhí)行三次,因?yàn)镮ntel記錄了第一次執(zhí)行可以/將以與第二次執(zhí)行不同的速度運(yùn)行的事實(shí)(他們建議的是三次,所以三次)。
然后執(zhí)行正在測(cè)試的代碼、強(qiáng)制序列化的另一個(gè)cpuid和最后的rdtsc以獲得代碼完成后的時(shí)間。
同時(shí),您希望使用操作系統(tǒng)提供的任何方式來(lái)強(qiáng)制在一個(gè)進(jìn)程/核心上運(yùn)行所有這些。在大多數(shù)情況下,您還希望強(qiáng)制代碼對(duì)齊-對(duì)齊方式的更改會(huì)導(dǎo)致執(zhí)行Spee中相當(dāng)大的差異。
最后,你想要多次執(zhí)行它-它總是有可能在中間被打斷(例如,任務(wù)切換),所以你需要做好準(zhǔn)備,一次執(zhí)行所需的時(shí)間要比其他時(shí)間長(zhǎng)得多-例如,5次運(yùn)行每次花費(fèi)40到43次時(shí)鐘周期,第六次執(zhí)行需要10000多個(gè)時(shí)鐘周期。顯然,在后一種情況下,您只需排除異常值-這不是來(lái)自您的代碼。
摘要:設(shè)法執(zhí)行rdtsc指令本身(幾乎)是你最不擔(dān)心的。更多的是你需要在您從rdtsc
那實(shí)際上意味著什么。