Linux clock_gettime()过去了吗?

时间:2014-04-15 04:53:28

标签: linux time clock

我试图在linux上获得高分辨率的时间戳。使用clock_gettime(),如下所示,我得到了#34; spike"经过近26微秒的时间看起来非常可怕。大多数" dt"约为30 ns。我在linux 2.6.32,Red Hat 4.4.6上。 ' lscpu'显示CPU MHz = 2666.121。我认为这意味着每个时钟滴答需要大约2 ns。因此,要求ns解决方案在这里看起来不太合理。

程序的输出(抱歉,我不能发布这个而不是列表。它认为它的代码有些如何)

  • 1397534268,40823395 1397534268,40827950,dt = 4555
  • 1397534268,41233555 1397534268,41236716,dt = 3161
  • 1397534268,41389902 1397534268,41392922,dt = 3020
  • 1397534268,46488430 1397534268,46491674,dt = 3244
  • 1397534268,46531297 1397534268,46534279,dt = 2982
  • 1397534268,46823368 1397534268,46849336,dt = 25968
  • 1397534268,46915657 1397534268,46918663,dt = 3006
  • 1397534268,51488643 1397534268,51491791,dt = 3148
  • 1397534268,51530490 1397534268,51533496,dt = 3006
  • 1397534268,51823307 1397534268,51826904,dt = 3597
  • 1397534268,55823359 1397534268,55827826,dt = 4467
  • 1397534268,60531184 1397534268,60534183,dt = 2999
  • 1397534268,60823381 1397534268,60844866,dt = 21485
  • 1397534268,60913003 1397534268,60915998,dt = 2995
  • 1397534268,65823269 1397534268,65827742,dt = 4473
  • 1397534268,70823376 1397534268,70835280,dt = 11904
  • 1397534268,75823489 1397534268,75828872,dt = 5383
  • 1397534268,80823503 1397534268,80859500,dt = 35997
  • 1397534268,86823381 1397534268,86831907,dt = 8526

有什么想法吗?感谢

#include <vector>
#include <iostream>
#include <time.h>
long long elapse( const timespec& t1, const timespec& t2 ) 
{
    return ( t2.tv_sec * 1000000000L + t2.tv_nsec ) - 
        t1.tv_sec * 1000000000L + t1.tv_nsec ); 

}
int main()
{
    const unsigned n=30000;
    timespec ts;
    std::vector<timespec> t( n );
    for( unsigned i=0; i < n; ++i )
    {
        clock_gettime( CLOCK_REALTIME, &ts );
        t[i] = ts;
    }
    std::vector<long> dt( n );
    for( unsigned i=1; i < n; ++i )
    {
        dt[i] = elapse( t[i-1], t[i] );
        if( dt[i] > 1000 )
        {
            std::cerr << 
                t[i-1].tv_sec << "," 
                << t[i-1].tv_nsec << " " 
                << t[i].tv_sec << "," 
                << t[i].tv_nsec 
                << ",dt=" << dt[i] << std::endl;
        }
        else 
        { 
            //normally I get dt[i] = approx 30-35 nano secs 
        }
    }
    return 0;
}

3 个答案:

答案 0 :(得分:2)

您引用的数字在3到30微秒范围内(3,000到30,000纳秒)。这是一个太短的时间来成为另一个线程/进程的上下文切换,让另一个线程运行,并将上下文切换回您的线程。很可能内核使用运行进程的核心来为外部中断(例如网卡,磁盘,计时器)提供服务,然后返回运行进程。

您可以使用此命令

观看linux中断计数器(每个CPU核心和每个源)
watch -d -n 0.2 cat /proc/interrupts

-n 0.2将导致命令以5Hz发出,-d标志将突出显示已更改的内容。

中断源也可以是TLB shootdown,这会产生IPIInter-Processor Interrupt)。您可以阅读有关TLB shootdowns here的更多信息。

如果要减少运行线程/进程的核心所服务的中断数,则需要设置中断关联。您可以了解有关Red Hat Interrupts和IRQ(中断请求)调优herehere的更多信息。

值得注意的是,您使用的CLOCK_REALTIME并不能保证“平滑”#34;它可以在系统时钟为"disciplined"时跳转,以保持准确时间通过NTP(网络时间协议)或PTP(精确时间协议)等服务。出于您的目的,最好使用CLOCK_MONOTONIC,您可以阅读有关差异here的更多信息。当时钟受到纪律处分时#34;时钟可以跳过&#34;步骤&#34; - 这是不寻常的,当然不是你看到的许多尖峰的原因。

答案 1 :(得分:1)

你能用clock_getres()来检查分辨率吗?

答案 2 :(得分:1)

我怀疑你在这里测量的是“OS Noise”。这通常是由您的程序被操作系统抢占所致。然后,操作系统执行其他工作。原因很多,但通常是:其他可运行的任务,硬件中断或计时器事件。

FTQ / FWQ基准旨在衡量这一特征,摘要中包含一些进一步的信息: https://asc.llnl.gov/sequoia/benchmarks/FTQ_summary_v1.1.pdf