Mau*_*aus 5 c++ linux posix timestamp
我正在使用开源库进行 i2c 总线操作。这个库经常使用一个函数来获取毫秒分辨率的实际时间戳。
示例调用:
nowtime = timer_nowtime();
while ((i2c_CheckBit(dev) == true) && ((timer_nowtime() - nowtime) < I2C_TIMEOUT));
Run Code Online (Sandbox Code Playgroud)
使用此 i2c 库的应用程序使用大量 CPU 容量。我发现,运行程序最多的时候是调用函数timer_nowtime()。
原函数:
unsigned long timer_nowtime(void) {
static bool usetimer = false;
static unsigned long long inittime;
struct tms cputime;
if (usetimer == false)
{
inittime = (unsigned long long)times(&cputime);
usetimer = true;
}
return (unsigned long)((times(&cputime) - inittime)*1000UL/sysconf(_SC_CLK_TCK));
}
Run Code Online (Sandbox Code Playgroud)
我现在的目标是,提高这个功能的效率。我是这样试的:
struct timespec systemtime;
clock_gettime(CLOCK_REALTIME, &systemtime);
//convert the to milliseconds timestamp
// incorrect way, because (1 / 1000000UL) always returns 0 -> thanks Pace
//return (unsigned long) ( (systemtime.tv_sec * 1000UL) + (systemtime.tv_nsec
// * (1 / 1000000UL)));
return (unsigned long) ((systemtime.tv_sec * 1000UL)
+ (systemtime.tv_nsec / 1000000UL));
Run Code Online (Sandbox Code Playgroud)
不幸的是,我不能内联声明这个函数(不知道为什么)。
哪种方式更有效地获得毫秒分辨率的实际时间戳?我相信有一种更高效的方法可以做到这一点。有什么建议?
谢谢。
很明显,您的示例调用在timer_nowtime()函数中使用了大部分 CPU 时间。您正在进行轮询,循环会占用您的 CPU 时间。您可以将计时器函数替换为更好的替代方案,这样您就可以实现更多的循环迭代,但它仍然会在该函数中使用大部分 CPU 时间!您不会通过更改计时器功能来实现使用更少的 CPU 时间!
您可以更改循环并引入等待时间 - 但前提是它在您的应用程序中有意义,例如:
start = timer_nowtime();
while( i2c_CheckBit(dev) ) {
now = timer_nowtime();
diff = now - start;
if( diff < I2C_TIMEOUT ) break;
else if( diff > SOME_TRESHOLD ) usleep( 1000*std::max(1,I2C_TIMEOUT-diff-SOME_SMALL_NUMBER_1_TO_10_MAYBE) );
}
Run Code Online (Sandbox Code Playgroud)
计时器:我认为gettimeofday()这是一个不错的决定,它具有高精度并且在大多数(所有?)Unice 中都可用。