给出while循环和函数排序如下:
int k=0;
int total=100;
while(k<total){
doSomething();
if(approx. t milliseconds elapsed) { measure(); }
++k;
}
我想每隔t毫秒执行一次'测量'。但是,由于'doSomething'可以接近上次执行时的第t毫秒,因此可以在从最后一次测量开始经过大约t毫秒后执行该测量。 我的问题是:如何实现这一目标?
一种解决方案是将计时器设置为零,并在每次'doSomething'之后测量它。当它处于可接受的范围内时,我执行测量并重置。但是,我不应该使用哪种c ++函数来完成这样的任务。我可以看到,有一些功能,但关于哪一个最合适的辩论超出了我的理解范围。请注意,某些函数实际上考虑了其他一些进程所花费的时间,但我希望我的计时器只能测量执行c ++代码的时间(我希望这很清楚)。另一件事是测量的分辨率,如下所述。假设建议的媒介选项。
答案 0 :(得分:2)
高分辨率计时是特定于平台的,您尚未在问题中指定。标准库clock()函数返回一个以每秒CLOCKS_PER_SEC递增的计数。在某些平台上,这可能足够快,可以为您提供所需的分辨率,但您应该检查系统的滴答速率,因为它是实现定义的。但是,如果你发现它足够高,那么:
#define SAMPLE_PERIOD_MS 100
#define SAMPLE_PERIOD_TICKS ((CLOCKS_PER_SEC * SAMPLE_PERIOD_MS) / 1000)
int k=0;
int total=100;
clock_t measure_time = clock() + SAMPLE_PERIOD_TICKS ;
while(k<total)
{
doSomething();
if( clock() - measure_time > 0 )
{
measure();
measure_time += SAMPLE_PERIOD_TICKS ;
++k;
}
}
如果需要,您可以将clock()替换为其他高分辨率时钟源。
但请注意几个问题。这种方法是“忙循环”;除非doSomething()或measure()产生CPU,否则该进程将占用所有cpu周期。如果这是目标上运行的唯一代码,那可能无关紧要。另一方面,这是在诸如Windows或Linux之类的通用OS上运行的,这些OS不是实时的,该过程可能被其他过程抢占,这可能影响采样周期的准确性。如果您需要精确计时使用RTOS并在单独的线程中执行doSomething()和measure()会更好。即使在GPOS中也会更好。例如,一般模式(在没有任何规范的情况下使用伪造的API)将是:
int main()
{
StartThread( measure_thread, HIGH_PRIORITY ) ;
for(;;)
{
doSomething() ;
}
}
void measure_thread()
{
for(;;)
{
measure() ;
sleep( SAMPLE_PERIOD_MS ) ;
}
}
measure_thread()
的代码仅在measure()
的运行时间可以忽略不计时才准确无误。如果需要很长时间,您可能需要考虑到这一点。如果它是非确定性的,您甚至可能必须测量其执行时间,以便将其减去睡眠时间。