35 delphi optimization performance gettickcount
确定处理例程所需的时间(例如函数的过程)最好和最准确的方法是什么?
我问,因为我目前正在尝试优化我的应用程序中的一些函数,当我测试更改时,如果有任何改进,只需通过查看就很难确定.因此,如果我能够返回一个准确或接近准确的处理例程的时间,那么我可以更清楚地了解代码是否有任何变化.
我考虑过使用GetTickCount,但我不确定这是否接近准确?
有一个可恢复的函数/过程来计算例程的时间是有用的,并使用它像这样:
// < prepare for calcuation of code
...
ExecuteSomeCode; // < code to test
...
// < stop calcuating code and return time it took to process
Run Code Online (Sandbox Code Playgroud)
我期待听到一些建议.
谢谢.
克雷格.
RBA*_*RBA 23
据我所知,最准确的方法是使用QueryPerformanceFrequency:
码:
var
Freq, StartCount, StopCount: Int64;
TimingSeconds: real;
begin
QueryPerformanceFrequency(Freq);
QueryPerformanceCounter(StartCount);
// Execute process that you want to time: ...
QueryPerformanceCounter(StopCount);
TimingSeconds := (StopCount - StartCount) / Freq;
// Display timing: ...
end;
Run Code Online (Sandbox Code Playgroud)
Joh*_*ica 14
从Delphi 6开始,您可以使用x86 Timestamp计数器.
这计算CPU周期,在1 Ghz处理器上,每个计数需要1纳秒.
无法获得更准确的信息.
function RDTSC: Int64; assembler;
asm
// RDTSC can be executed out of order, so the pipeline needs to be flushed
// to prevent RDTSC from executing before your code is finished.
// Flush the pipeline
XOR eax, eax
PUSH EBX
CPUID
POP EBX
RDTSC //Get the CPU's time stamp counter.
end;
Run Code Online (Sandbox Code Playgroud)
在x64上,以下代码更准确,因为它不会受到延迟的影响CPUID.
rdtscp // On x64 we can use the serializing version of RDTSC
push rbx // Serialize the code after, to avoid OoO sneaking in
push rax // subsequent instructions prior to executing RDTSCP.
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
shl rdx,32
or rax,rdx
Run Code Online (Sandbox Code Playgroud)
使用上面的代码获取执行代码之前和之后的时间戳.
最准确的方法可能和馅饼一样容易.
请注意,您需要至少运行10次测试以获得良好的结果,在第一次传递时,缓存将变冷,随机硬盘读取和中断可能会导致您的计时失效.
因为这个东西是如此准确,如果你只是第一次运行,它可能会给你错误的想法.
为什么你不应该使用QueryPerformanceCounter()
QueryPerformanceCounter()给CPU 相同的时间,如果CPU减慢,它补偿CPU thottling.如果你的CPU由于过热或诸如此类的原因而减速,那么RDTSC会给你相同的周期数.
因此,如果你的CPU开始变热并且需要减速,那么QueryPerformanceCounter()会说你的例程花费更多的时间(这是误导性的),并且RDTSC会说它需要相同的周期数(这是准确的).
这是你想要的,因为你对你的代码使用的CPU周期数感兴趣,而不是挂钟时间.
来自最新的英特尔文档:http://software.intel.com/en-us/articles/measure-code-sections-using-the-enhanced-timer/?wapkw =%28rdtsc%29
使用处理器时钟
这个计时器非常准确.在具有3GHz处理器的系统上,此计时器可以测量持续时间小于1纳秒的事件.[...]如果在目标代码运行时频率发生变化,则最终读数将是多余的,因为不使用相同的时钟频率进行初始和最终读数.在此期间发生的时钟滴答数将是准确的,但经过的时间将是未知的.
何时不使用RDTSC
RDTSC对基本时序非常有用.如果您在单个CPU机器上计时多线程代码,RDTSC将正常工作.如果您有多个CPU,则startcount可能来自一个CPU而endcount来自另一个CPU.
所以不要使用RDTSC来计算多CPU机器上的多线程代码.在单CPU机器上它可以正常工作,或者在多CPU机器上使用单线程代码也可以.
还记得RDTSC计算CPU周期.如果有一些需要时间但不使用CPU的东西,比如磁盘IO或网络而不是RDTSC不是一个好工具.
但文档说RDTSC在现代CPU上不准确
RDTSC 不是一个跟踪时间的工具,它是一个跟踪CPU周期的工具.
为此,它是唯一准确的工具.跟踪时间的例程在现代CPU上并不准确,因为CPU时钟并不像以前那样绝对.
Uwe*_*abe 10
您没有指定Delphi版本,但Delphi XE在单元诊断中声明了TStopWatch.这将允许您以合理的精度测量运行时间.
uses
Diagnostics;
var
sw: TStopWatch;
begin
sw := TStopWatch.StartNew;
<dosomething>
Writeln(Format('runtime: %d ms', [sw.ElapsedMilliseconds]));
end;
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
6466 次 |
| 最近记录: |