我讀過RDTSC可以給出錯誤的讀數,不應該依賴。
這是真的嗎?如果是的話,可以做些什麼呢?如何確保RDTSC準確?
2
A
回答
4
非常舊的CPU的RDTSC是準確的。
問題
但是新的CPU有問題。
工程師們認爲RDTSC對於講述時間會很有幫助。
但是,如果CPU節制頻率RDTSC是無用的告訴時間。
上述braindead工程師決定通過讓TSC始終以相同的頻率運行,即使CPU速度變慢來「解決」這個問題。
這具有TSC可用於告訴已過時(掛鐘)時間的'優勢'。但是它使得TSC
無用
對分析的用處不大。
如何判斷你的CPU不破
如果你可以告訴你的CPU是通過讀取TSC_invariant
位在CPUID罰款。
設置AEX
爲80000007H並讀取EDX
的第8位。
如果它是0,那麼你的CPU很好。
如果它是1,那麼你的CPU壞了,你需要確保你的配置文件,而全速運行CPU。
function IsTimerBroken: boolean;
{$ifdef CPUX86}
asm
//Make sure RDTSC measure CPU cycles, not wall clock time.
push ebx
mov eax,$80000007 //Has TSC Invariant support?
cpuid
pop ebx
xor eax,eax //Assume no
and edx,$10 //test TSC_invariant bit
setnz al //if set, return true, your PC is broken.
end;
{$endif}
//Make sure RDTSC measure CPU cycles, not wall clock time.
{$ifdef CPUX64}
asm
mov r8,rbx
mov eax,$80000007 //TSC Invariant support?
cpuid
mov rbx,r8
xor eax,eax
and edx,$10 //test bit 8
setnz al
end;
{$endif}
如何解決亂序執行的問題
參見:http://www.intel.de/content/dam/www/public/us/en/documents/white-papers/ia-32-ia-64-benchmark-code-execution-paper.pdf
使用下面的代碼:
function RDTSC: int64;
{$IFDEF CPUX64}
asm
{$IFDEF AllowOutOfOrder}
rdtsc
{$ELSE}
rdtscp // On x64 we can use the serializing version of RDTSC
push rbx // Serialize the code after, to avoid OoO sneaking in
push rax // later instructions before the RDTSCP runs.
push rdx // See: http://www.intel.de/content/dam/www/public/us/en/documents/white-papers/ia-32-ia-64-benchmark-code-execution-paper.pdf
xor eax,eax
cpuid
pop rdx
pop rax
pop rbx
{$ENDIF}
shl rdx,32
or rax,rdx
{$ELSE}
{$IFDEF CPUX86}
asm
{$IFNDEF AllowOutOfOrder}
xor eax,eax
push ebx
cpuid // On x86 we can't assume the existance of RDTSP
pop ebx // so use CPUID to serialize
{$ENDIF}
rdtsc
{$ELSE}
error!
{$ENDIF}
{$ENDIF}
end;
如何破碎的CPU上運行RDTSC
訣竅是強制CPU以100%運行。
這通常通過多次運行示例代碼來完成。
我通常使用1.000.000開始。
然後,我會將那100萬次運行10次,並採取這些嘗試的最低時間。
與理論計時比較表明,這給出非常準確的結果。
相關問題
- 1. 如何確保fgets準確接受前導0的數字?
- 2. 如何確保PostgreSQL表中彙總數據的準確性?
- 3. 如何確保發送到服務器的GPS位置準確?
- 4. 如何確保數據保存在Parse.com並準備檢索Android
- 5. 如何找出準確度?
- 6. 如何確保模
- 7. CLLocation準確度有多準確?
- 8. 如何確保使用正確的DateTime?
- 9. 重複每月和每年的事件 - 如何確保準確性?
- 10. 如何在Yii中保存數據並確保正確保存?
- 11. 使用curator treeCache時,如何確保緩存準備就緒?
- 12. 修改DOM後如何確保DOM已準備好再次
- 13. 如何準確確定何時發送HTTP請求?
- 14. NSTimer不準確?
- 15. NSTimer準確性
- 16. Pytesser不準確
- 17. GMSCameraPosition不準確
- 18. CountDownTimer不準確
- 19. datetime.now()不準確
- 20. DispatchQueue.main.asyncAfter不準確
- 21. 如何正確保存javax.persistence.ManyToOne
- 22. 如何確保電子書?
- 23. 如何確保UITableViewCell可見?
- 24. 如何確保非負列?
- 25. 如何確保README.rst有效?
- 26. 準確的基準代碼
- 27. 對於大n,java.lang.Math.pow(x,n)的準確性/精確性如何?
- 28. 如何準確確定SPFile實例是否爲轉換文件?
- 29. 如何在windows vista上更精確準確地剖析代碼?
- 30. 如何準確確定日期已隨UIApplicationSignificantTimeChange更改?
TSC還有一個特性位,它在hlt睡眠狀態期間不會停止,這也使得它不能用作時間源。 Linux/proc/cpuinfo調用這個'nonstop_tsc'。由於亂序執行,使用'rdtsc'來定時極短的指令序列也是有問題的。 'rdtscp'可以提供幫助,但其他用途可能需要一個完整的序列化指令來確保'rdtsc'指令不能通過其他insn,而其他insns不會通過它。爲了分析,使用perf計數器。 –
@PeterCordes Perf計數器吸。這就是爲什麼我們需要'rdtsc'爲什麼它被打破對我來說是一個謎。它會殺死英特爾添加一個與主時鐘運行/不同步的額外定時器嗎? – Johan
我通常沒有把我的microbenchmark放入一個足夠大的循環來使用perf計數器的問題。對於非常短的序列,您可以使用IACA或手動計數(使用Agner Fog的表格和uarch指南)來估計吞吐量/延遲/融合域計數。我想這將是一個真正的週期櫃檯,我不能不同意。 IDK實施起來會花多少錢。可能不是很。但是,如果我不得不選擇低開銷的高精度時間源,那麼我會選擇它。 –