Windows 带有 MinGW C 的 QueryPerformanceCounter

Windows QueryPerformanceCounter with MinGW C

我正在尝试通过拉取 QueryPerformanceCounter (QPC) 来测量串行协议握手的响应时间。我的目标系统是 Asrock D1800b Intel 双核上的 win7,使用最新版本的 MinGw (6.3.0-1) 编译。

为了测试QPC我有这个代码:

#include <windows.h>
#include <stdio.h>

void main() 
{
    //performance timers
    LARGE_INTEGER StartingTime, EndingTime, ElapsedMicroseconds;
    LARGE_INTEGER Frequency;

    QueryPerformanceFrequency(&Frequency);
    for (int i = 0 ; i < 10 ; i++) 
    {
        QueryPerformanceCounter(&StartingTime);
        Sleep(10); //ms
        QueryPerformanceCounter(&EndingTime);
        ElapsedMicroseconds.QuadPart = EndingTime.QuadPart - StartingTime.QuadPart;
        ElapsedMicroseconds.QuadPart *= 1000000;                //first scale up counts
        ElapsedMicroseconds.QuadPart /= Frequency.QuadPart;     //then convert to us
        printf("elapsed=%li\n", ElapsedMicroseconds.QuadPart);
    }

}

当 运行 在目标系统上时,我得到:(没有其他负载)

elapsed=5341
elapsed=14086
elapsed=13818
elapsed=14322
elapsed=15305
elapsed=8867
elapsed=12162
elapsed=14225
elapsed=13333
elapsed=14751

但是当 运行 在开发系统(Win10、Intel i5)上时,我得到了如此一致的结果

elapsed=11326
elapsed=11556
elapsed=12630
elapsed=11583
elapsed=11749
elapsed=12644
elapsed=12562
elapsed=11690
elapsed=11726
elapsed=11664

以上两个结果都是更大 运行.

的示例

预期结果在 10000us 以上。

那么,关于它在目标系统上发生的事情有什么想法吗?

您可能需要提高节拍率,默认情况下可能为 64hz(每个节拍 15.625 毫秒)以使 Sleep(10) 按预期工作。您可以将其增加到 1000hz(每滴答 1 毫秒)。这会增加中断开销,但结果应该更一致。示例代码片段:

    timeBeginPeriod(1);                     /* set ticker to 1000 hz */
    Sleep(128);                             /* wait for it to settle */
    /* ... benchmark code */
    timeEndPeriod(1);                       /* restore ticker to default */

注意,虽然 Windows 不是实时的 OS,但在 Windows 中有可能以固定频率获得一个线程到 运行 而没有任何漂移, 并尽可能使用 Sleep(1) 以避免在固定频率线程中绑定 cpu 。 运行 如果存在竞争线程,优先级稍高的线程会有所帮助。这经常被需要 "physics engine" 线程且 运行 以固定频率运行的游戏使用。示例代码包含在这个老问题的答案中:

How to coordinate threads properly based on a fixed cycle frequency?

基于link中示例的程序输出示例,使用固定频率100hz,运行100次。每一步都有一些变化,但没有整体漂移。

 100 deltas in ms:

  9.99973023  10.00002346  10.00002346  10.00002346 
 10.00002346  10.00002346  10.00676775  10.00002346 
 10.00002346  10.00002346  10.00794067  10.00002346 
  9.99973023  10.00002346  10.00002346  10.00002346 
 10.00002346  10.00618129  10.00002346  10.00002346 
 10.00002346  10.00002346  10.00002346  10.00002346 
 10.00002346   9.99973023  10.00002346  10.00002346 
 10.00002346  10.00002346  10.00002346  10.00002346 
 10.00090315  10.00148961  10.00148961  10.00090315 
 10.00002346  10.00178284  10.00002346  10.00002346 
 10.00295576  10.00002346  10.00882036  10.00500837 
 10.00002346  10.00559483  10.00559483  10.00647452 
 10.00588806  10.00735421  10.00676775  10.00764744 
 10.00002346  10.00002346  10.00823390  10.00002346 
 10.00002346  10.00002346  10.00002346  10.00002346 
 10.00002346  10.00002346   9.99973023  10.00002346 
 10.00002346  10.00002346  10.00002346  10.00002346 
 10.00002346  10.00002346  10.00002346  10.00002346 
 10.00002346  10.00002346  10.00002346   9.99973023 
 10.00002346  10.00002346  10.00002346  10.00002346 
 10.00002346  10.00002346  10.00002346  10.00002346 
 10.00002346  10.00002346  10.00002346   9.99973023 
 10.00002346  10.00002346  10.00002346  10.00002346 
 10.00002346  10.00002346  10.00002346  10.00002346 
 10.00002346  10.00002346  10.00002346  10.00002346 

elapsed time in ms:

1000.000000000000