Clock_Gettime() 抖动?

Posted

技术标签:

【中文标题】Clock_Gettime() 抖动?【英文标题】:Clock_Gettime() Jitter? 【发布时间】:2015-06-08 03:28:04 【问题描述】:

我在 Linux 2.6 上使用 clock_gettime()(来自 time.h)来控制我的线程循环中的时间。我需要在 +/- 5mS 时间范围内 500mS。它似乎给了我 500 毫秒的时间,然后开始漂移或抖动到 +/- 30 毫秒:

我正在使用 CLOCK_REALTIME 调用。有什么办法可以改善它的偏差吗?我只是用它计算每毫秒,一旦计数器达到 500,就会触发中断。

这也在 QT 4.3 框架内。 QTimer 似乎比这更紧张。

【问题讨论】:

也许你可以展示你用来测试的代码。有时,由于某些累加器逻辑,这些事情最终会归结为数值精度。 我们需要有关您的系统和代码的更多信息。你在使用一些过时的嵌入式系统吗?在某些 ARM 架构上,睡眠的精度不可能超过几毫秒。一些架构没有高精度定时器,它们的任务切换频率为 100 Hz -> 可用的睡眠精度约为 10 ms。 【参考方案1】:

根据您问题的措辞,我感觉您可能错误地累积了您的时差。

试试这个方法:

#include <stdio.h>
#include <time.h>

long elapsed_milli( struct timespec * t1, struct timespec *t2 )

    return (long)(t2->tv_sec - t1->tv_sec) * 1000L
         + (t2->tv_nsec - t1->tv_nsec) / 1000000L;


int main()

    const long period_milli = 500;
    struct timespec ts_last;
    struct timespec ts_next;
    const struct timespec ts_sleep =  0, 1000000L ;

    clock_gettime( CLOCK_REALTIME, &ts_last );

    while( 1 )
    
        nanosleep( &ts_sleep, NULL );
        clock_gettime( CLOCK_REALTIME, &ts_next );
        long elapsed = elapsed_milli( &ts_last, &ts_next );

        if( elapsed >= period_milli )
        
            printf( "Elapsed : %ld\n", elapsed );

            ts_last.tv_nsec += period_milli * 1000000L;
            if( ts_last.tv_nsec >= 1000000000L )
            
                ts_last.tv_nsec -= 1000000000L;
                ts_last.tv_sec++;
            
        
    
    return 0;

每次经过所需时间段时,都会更新“先前”时间以使用经过该时间段的预期时间,而不是实际时间。此示例在每次轮询之间使用 1 毫秒的睡眠时间,这可能会超出顶部。

【讨论】:

以上是关于Clock_Gettime() 抖动?的主要内容,如果未能解决你的问题,请参考以下文章

clock_gettime() 没有给出正确的输出[重复]

clock_gettime的介绍说明

clock_gettime的主要例子

使用clock_gettime在arduino中进行纳秒测量

使用 ICC 在 Linux 中未定义的对 clock_gettime() 的引用

vDSO 笔记:相关代码:glibc clock_gettime()