分析 API 调用时如何将滴答转换为时钟周期

How to convert ticks to clock cycles when profiling API calls

我正在分析 Direct3D9 API 调用。我已经阅读了很多描述该过程的文档 here。我有一个关于计算经过的时钟周期的问题。这是我目前的方法:

// measurement vars
LARGE_INTEGER start, stop, freq;

//
// flush command buffer here
//

// 
// issue begin query here
//

// start timer
QueryPerformanceCounter(&start);

//
//draw
//

//
// issue end query here and wait on results
//

// stop timer
QueryPerformanceCounter(&stop);

// calc elapsed ticks
stop.QuadPart -= start.QuadPart;

// get frequency
QueryPerformanceFrequency(&freq);

// ticks for easier handling
ULONG ticks = stop.QuadPart;

// calc elapsed clock cycles
cycles = (2.8E9 * ticks) / (double)freq.QuadPart;

我的问题涉及应该代表处理器速度的值 2.8E9。这是计算时钟周期的正确方法吗?我正在分析单个 API 调用,我的结果与上述 link 中的结果不同。如果我将处理器速度设置为 1E9 那么数字在范围内...我只是想检查我的方法...

处理器周期数(大约)是差异。

LONGLONG cycles = stop.QuadPart - start.QuadPart;

转换为 SECONDS 的正确方法是:

double seconds = (double)cycles / (double)freq.QuadPart;

QueryPerformanceCounter 曾经作为 RDTSC 的包装器实现,但这不适用于现代时钟频率步进电源管理。因此,QPC 现在通常是系统上的其他稳定时钟,因此它不一定是“CPU 个处理器周期”。

如果你真的想要 true 'CPU processor cycles' 那么你应该直接使用 __rdtsc() intrinsic,但请记住你没有一个可靠的方法将它直接转换为时间——而在旧的 AMD 上Athalon 64 机器你有它在核心之间不同步的问题。

保留使用 ticks 调用 GetTickCCount64(或已弃用的 GetTickCCount),其中 returns "ticks in milliseconds".

Acquiring high-resolution time stamps