0

我编写了一个代码来确保 while(1) 循环的每个循环都花费特定的时间(在本例中为 10000µS,等于 0.01 秒)。问题是这段代码在开始时运行良好,但不到一分钟就停止了。就像访问linux时间有限制一样。现在,我正在初始化一个布尔变量,以使这个时间计算运行一次而不是无限。由于性能随时间而变化,因此最好计算每个循环的计算时间。有没有其他方法可以做到这一点?

void some_function(){
struct timeval tstart,tend;
while (1){
   gettimeofday (&tstart, NULL);
   ...
   Some computation
   ...
   gettimeofday (&tend, NULL);
   diff = (tend.tv_sec - tstart.tv_sec)*1000000L+(tend.tv_usec - tstart.tv_usec);
   usleep(10000-diff);
   }
}
4

2 回答 2

2

来自 usleep 的手册页

 #include <unistd.h>

 int usleep(useconds_t usec);

usec 是 unsigned int,现在猜猜下一行中 diff > 10000 时会发生什么

 usleep(10000-diff);
于 2017-09-25T08:19:35.207 回答
0

好吧,您为获得差异而进行的计算是错误的:

diff = (tend.tv_sec - tstart.tv_sec)*1000000L+(tend.tv_usec - tstart.tv_usec);

您正在混合不同的整数类型,缺少tv_usec可能是一个unsigned数量,您正在从另一个中减去它unsigned并且可能溢出....之后,您会得到整整一秒加上大约4.0E09usec. 这是大约 4000 秒。或一个多小时……大约。最好检查是否有进位,在这种情况下,增加tv_sec,然后减去10000000tv_usec获得适当的正值。

我不知道您正在使用的实现,struct timeval但最有可能的是它tv_sec是一个time_t(这甚至可以是 64 位),而tv_usec通常只是一个unsigned32 位的值,因为它不会从1000000.

让我来说明一下……假设您已经用了 100 毫秒的时间进行计算……而这恰好发生在一秒钟的中间……您有

tstart.tv_sec = 123456789; tstart.tv_usec = 123456;
tend.tv_sec = 123456789; tend.tv_usec = 223456;  

当你减去时,它会导致:

tv_sec = 0; tv_usec = 100000;

但是让我们假设您在第二个更改时完成了计算

tstart.tv_sec = 123456789; tstart.tv_usec = 923456;
tend.tv_sec =  123456790; tend.tv_usec = 23456;

时间差又是 100 毫秒,但是现在,当你计算你的表达式时,你得到的第一部分是 1000000(整整一秒),但是在减去第二部分之后,你会得到23456 - 923456 =*=> 4294067296(*) 溢出。所以你达到usleep(4295067296)4295s.更多1h 11m。我认为您没有足够的耐心等待它完成......但这可能会发生在您的程序中,具体取决于struct timeval定义方式。

进行工作的正确方法是重新排序总和以先进行所有加法,然后再进行减法。这在处理signedand时强制强制转换为有符号整数unsigned,并防止 s 中的负溢出unsigned

diff = (tend.tv_sec - tstart.tv_sec) * 1000000 + tstart.tv_usec - tend.tv_usec;

被解析为

diff = (((tend.tv_sec - tstart.tv_sec) * 1000000) + tstart.tv_usec) - tend.tv_usec;
于 2017-09-28T06:22:19.293 回答