我试图在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解决方案在这里看起来不太合理。
程序的输出(抱歉,我不能发布这个而不是列表。它认为它的代码有些如何)
有什么想法吗?感谢
#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;
}
答案 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
,这会产生IPI
(Inter-Processor Interrupt)。您可以阅读有关TLB shootdowns here的更多信息。
如果要减少运行线程/进程的核心所服务的中断数,则需要设置中断关联。您可以了解有关Red Hat Interrupts和IRQ(中断请求)调优here和here的更多信息。
值得注意的是,您使用的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