QueryPerformanceCounter

QueryPerformanceCounter

我创建了一个简单的程序来确定QueryPerformanceCounter调用需要多长时间。
在我的计算机上大约需要8纳秒,但有时我会看到一些尖峰,每次调用最多可能会消耗500 uscs。

一些细节:
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个usecs跃升到550个usecs很大

问题:
  • 有谁知道为什么会发生这种情况以及是否可以消除这些尖峰?
  • 是真的需要这500个usecs进行调用(这次是使用阻塞线程)还是只返回“不正确”值,但不影响线程执行?

  • 谢谢。

    最佳答案

    可以猜测,发生的情况是,您不时地对进程切换进行计时(即,您的进程正在运行并从时钟中返回连续的值),但是在某个时候,进程调度程序会决定其他进程获得一点CPU时间(或者至少调度程序本身运行以确定其他进程是否应该获得一些CPU时间)。

    发生这种情况时,对QPC的 call 之一将显示出比其余大多数 call 大得多的增量。

    关于c++ - C++ QueryPerformanceCounter性能峰值,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/32095855/

    10-12 15:56