我读过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实施起来会花多少钱。可能不是很。但是,如果我不得不选择低开销的高精度时间源,那么我会选择它。 –