带有MinGW C的Windows QueryPerformanceCounter

时间:2018-08-27 19:01:56

标签: c performance time timer mingw

我试图通过拉QueryPerformanceCounter(QPC)来测量串行协议握手的响应时间。我的目标系统是Asrock D1800b Intel Dual Core上的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);
    }

}

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

  

经过的= 5341
  elapsed = 14086
  过去= 13818
  elapsed = 14322
  elapsed = 15305
  elapsed = 8867
  elapsed = 12162
  elapsed = 14225
  elapsed = 13333
  过去了= 14751

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

  

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

以上两个结果都是更大的结果示例。

预期结果在10000us以上。

那么,关于它在目标系统上发生什么的任何想法?

1 个答案:

答案 0 :(得分:1)

您可能需要提高滴答速度,为了使Sleep(10)正常工作,可能需要将滴答速度默认设置为64hz(每滴15.625毫秒)。您可以将其增加到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不是实时操作系统,但在Windows中可以使线程以固定频率运行而没有任何漂移,并在可能的情况下使用Sleep(1)避免以固定频率绑定cpu线。如果存在竞争线程,则以稍高的优先级运行线程将有所帮助。这通常需要需要以固定频率运行的“物理引擎”线程的游戏使用。这个旧问题的答案中包含示例代码:

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

基于链接中示例的程序的示例输出,使用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