c ++ QueryPerformanceCounter性能峰值

时间:2015-08-19 12:43:27

标签: c++ performance

我创建了一个简单的程序来确定QueryPerformanceCounter调用的时间。 我的计算机大约需要8纳秒,但有时我可以看到每次通话最多500个用户的峰值。

一些细节:
Visual Studio 2013,C ++

LARGE_INTEGER ll;
QueryPerformanceFrequency(&ll);
int steps = 10000000;
LARGE_INTEGER t1, t2;
long long dt=0, dtAvg=0, dtMax=0;
double NanoSecMult = 1000000000.0 / ll.QuadPart;
double UsecSecMult = 1000000.0 / ll.QuadPart;

for (int i = 0; i < steps; i++)
{
    QueryPerformanceCounter(&t1);
    QueryPerformanceCounter(&t2);
    dt = t2.QuadPart - t1.QuadPart;
    dtAvg += dt;
    if (dt>dtMax)
        dtMax = dt;
}
double dtd = dtAvg*UsecSecMult / steps;
double dtdMax = dtMax * UsecSecMult;
printf_s("steps: %d, dtAvg: %.12f usec, dtMax: %.6f usec\n", steps, dtd, dtdMax);

输出示例:

... 
steps: 10000000, dtAvg: 0.008456895938 usec, dtMax: 3.893501 usec
steps: 10000000, dtAvg: 0.008427907056 usec, dtMax: 222.991405 usec
steps: 10000000, dtAvg: 0.008488256317 usec, dtMax: 452.353993 usec
steps: 10000000, dtAvg: 0.008457002125 usec, dtMax: 433.594398 usec
steps: 10000000, dtAvg: 0.008493247077 usec, dtMax: 9.910729 usec
steps: 10000000, dtAvg: 0.008432154511 usec, dtMax: 10.618638 usec
steps: 10000000, dtAvg: 0.008588921008 usec, dtMax: 480.670362 usec
...

所以dtAvg几乎一直都是相同的,最后一位数字不同,但是dtMax从2个用户到550个用户跳了很多

问题:

  1. 有没有人知道为什么会发生这种情况,以及我是否可以消除这些高峰?
  2. 它是否真的需要这500个usec用于调用(此时使用阻塞线程)或它只返回“不正确”的值但不影响线程执行?
  3. 谢谢。

1 个答案:

答案 0 :(得分:6)

猜测一下,发生了什么事情,偶尔你会对进程切换进行计时 - 也就是说,你的进程正在运行并从时钟中返回连续值 - 但在某些时候,进程调度程序决定其他一些进程应该获得一点CPU时间(或者至少调度程序本身运行以确定其他进程是否应该获得一些CPU时间)。

当发生这种情况时,对QPC的一次调用将显示比其余大部分更大的增量。