如何缩短测量时差的时间量?

时间:2014-10-15 10:57:16

标签: c windows

我正在尝试衡量用户的反应时间。我的代码如下所示:

int clocks2ms(clock_t range) {
  return (int)((double)range*1000/CLOCKS_PER_SEC);
}

clock_t start = clock(); // start measuring
while(!kbhit()); // wait for keypress
int reaction = clocks2ms(clock()-start); // measure reaction

反应时间为186ms(+ -1ms),201ms,216ms等,因此间隙相等,为15ms。有没有办法缩短差距?我尝试以实时优先级

运行它
start "test" /Realtime "test.exe"

但没有改变。我想获得1ms的准确性。

3 个答案:

答案 0 :(得分:3)

您必须使用具有更高精度的计时器,例如GetPerformanceCounter()ref):

LARGE_INTEGER StartCounter;
LARGE_INTEGER EndCounter;
LARGE_INTEGER Frequency;

QueryPerformanceCounter(&StartCounter);
QueryPerformanceFrequency(&Frequency);

// Do stuff...

QueryPerformanceCounter(&EndCounter);

double TimeDelta = (EndCounter.QuadPart - StartCounter.QuadPart) / (double) Frequency.QuadPart;

请注意,我在上面的示例代码中省略了Query...函数的错误检查。

答案 1 :(得分:2)

获得更精确答案的两种方法。

同步开始。而不是在时钟滴答内启动 someplace ,而是在更改后立即启动。这通常会减少"抖动"一开始。这个想法在2中更好 - 它没有获得更精确的答案,但确实提高了准确性。

clock_t prestart = clock();
clock_t start,end;
while((start = clock()) == prestart);  //
puts("Hit Any Key");
fflush(stdout);
while(!kbhit()); // wait for keypress
end = clock();
int reaction = clocks2ms(end-start); 

结束样本后的时钟周期。这可能会提高精度,但取决于系统的稳定性 - 即正在进行的其他处理。

unsigned count = 0;
...
while(!kbhit()); // wait for keypress
end = clock();
while(end == clock()) count++;
int reaction = clocks2ms(end + (max_cnt_per_tck-count)/max_cnt_per_tck - start); 

当然,这些方法都不比@uesp建议的更高精度时钟更好。它们受制于系统的实时方面,例如print()时间的不一致或此线程代码之间可能发生的中断。但是当没有更精确的时间源时,他们确实提供了一些改进。

答案 2 :(得分:1)

如果kbhit()的时间分辨率是问题,那么您可以尝试一些替代方案:

  1. 由于kbhit()函数实际上是deprecated,因此使用_kbhit()函数可能会获得更好的结果。

  2. 如果您能够使用ncurses编译项目,则有一个getch()函数可以在不等待返回密钥的情况下获取字符。

  3. This question at the C FAQ列出了一些从控制台获取字符的其他方法,可能会产生更好的结果。