小编Arn*_*rno的帖子

如何获得linux gettimeofday()的微秒时间以及它的准确性是多少?

挂钟时间通常由系统RTC提供.这主要仅提供低至毫秒范围的时间,并且通常具有10-20毫秒的粒度.但是,gettimeofday()的分辨率/粒度通常报告在几微秒范围内.我假设微秒粒度必须来自不同的来源.

gettimeofday()的微秒分辨率/粒度是如何完成的?

当从RTC获取毫微秒的部分并且从不同的硬件获取微秒时,出现了两个源的定相问题.这两个来源必须以synchronized某种方式.

这两个来源之间的同步/阶段是如何完成的?

编辑:从我在amdn提供的链接中看到的,特别是以下的英特尔链接,我在这里添加一个问题:

是否gettimeofday()在微秒制度中提供分辨率/粒度?


编辑2:总结amdns 答案以及更多阅读结果:

Linux仅在启动时使用实时时钟(RTC)与更高分辨率的计数器同步,即Timestampcounter(TSC).引导后gettimeofday()返回一个完全基于TSC值和该计数器频率的时间.frequency通过将系统时间与外部时间源进行比较来校正/校准TSC的初始值.调整由adjtimex()函数完成/配置.内核运行锁相环以确保时间结果是单调且一致的.

这样可以说gettimeofday()具有微秒分辨率.考虑到更现代的Timestampcounter在GHz体系中运行,可获得的分辨率可能在纳秒范围内.因此这个有意义的评论

/**
407  * do_gettimeofday - Returns the time of day in a timeval
408  * @tv:         pointer to the timeval to be set
409  *
410  * NOTE: Users should be converted to using getnstimeofday()
411  */
Run Code Online (Sandbox Code Playgroud)

可以在Linux/kernel/time/timekeeping.c中找到.这表明在稍后的时间点可能存在更高分辨率的功能.现在getnstimeofday()只在内核空间中可用.

但是,查看所有涉及的代码以获得正确的信息,显示了很多关于不确定性的评论.有可能获得微秒分辨率.该功能gettimeofday()甚至可以在微秒方案中显示粒度.但是:由于driftTSC频率无法准确校正,因此对其准确性有严重的考虑.此外,在Linux中处理这个问题的代码的复杂性暗示着相信它实际上很难做到正确.这是特别的,但不仅仅是由Linux应该运行的大量硬件平台引起的.

结果: …

linux time linux-kernel

23
推荐指数
1
解决办法
1万
查看次数

Windows上的微秒级分辨率时间戳

如何在Windows上获得微秒级分辨率时间戳?

我正在寻找比QueryPerformanceCounter和更好的东西QueryPerformanceFrequency(这些只能给你一个自启动以来经过的时间,并且如果在不同的线程上调用它们不一定准确 - 也就是说,QueryPerformanceCounter可能在不同的CPU上返回不同的结果.还有一些处理器可以调整他们的节电频率,显然并不总是反映在他们的QueryPerformanceFrequency结果中.)

实现一个不断更新,高分辨率时间为Windows提供者,但它似乎并不稳固.当微秒问题看起来很棒,但它不能再下载了.

另一个资源是在Windows XP下获取准确的时间戳,但它需要许多步骤,运行辅助程序加上一些初始化的东西,我不确定它是否适用于多个CPU.

我还查看了维基百科文章时间戳计数器,它很有趣,但没那么有用.

如果答案只是用BSD或Linux来做,那就更容易了,这很好,但我想确认一下,并解释为什么在Windows中这么难以在Linux和BSD中这么容易.这是相同的精品硬件......

c++ windows time boost

16
推荐指数
5
解决办法
2万
查看次数

C:为什么fprintf(stdout,....)这么慢?

我仍然经常使用控制台输出来获取我的代码中发生的事情.我知道这可能有点老式,但我也用它来"管道"stdout到日志文件等.

但是,事实证明,由于某种原因,控制台的输出速度变慢了.我想知道是否有人可以解释为什么fprintf()到控制台窗口似乎有点阻塞.

到目前为止我做过/诊断过的事情:

  1. 我测量了fprintf(stdout,"quick fprintf\n"); 它需要的时间 :0.82ms(平均值).由于vsprintf_s(...)在几微秒内将相同的输出写入字符串,因此考虑的时间太长.因此,必须有一些专门针对控制台的阻止.

  2. 为了摆脱阻塞,我习惯vsprintf_s(...)将输出复制到一个类似于fifo的数据结构中.数据结构受临界区对象的保护.然后,单独的线程通过将排队的输出放入控制台来对数据结构进行取消.

  3. 我可以通过引入管道服务获得进一步的改进.我的程序的输出(应该最终在控制台窗口中)按以下方式进行:

    • A vsprintf_s(...)将输出格式化为简单字符串.
    • 这些字符串排队成一个类似于fifo的数据结构,例如链表结构.此数据结构受临界区对象的保护.
    • 第二个线程通过将输出字符串发送到命名管道来使数据结构出列.
    • 第二个进程读取命名管道并将字符串再次放入一个类似于fifo的数据结构中.这是为了使读数远离阻塞输出到控制台.读取过程快速读取命名管道并持续监视管道缓冲区的填充水平.
    • 第二个进程中的第二个线程最终将数据结构出列fprintf(stdout,...)到控制台.

所以我有两个进程,每个进程至少有两个线程,它们之间有一个命名管道,管道两侧有类似数据结构,以避免在管道缓冲区满时阻塞.

这是很多东西,以确保控制台输出是"非阻塞".但结果并不算太糟糕.我的主程序可以在几微秒内编写复杂的fprintf(stdout,...).

也许我之前应该问过:还有其他(更容易!)的方式来获得非阻塞控制台输出吗?

c

11
推荐指数
1
解决办法
6102
查看次数

为什么在有PIT可用时需要TSC

我正在阅读"了解Linux内核",其中有三个时钟

  1. 实时时钟

  2. 时间戳计数器(TSC)

  3. 可编程间隔定时器(PIT)

关于这些我几乎没有问题.

  1. 为什么计算机开机后不使用实时时钟?

  2. 系统运行时是否正在运行?

  3. TSC寄存器使用PIT,那么为什么我们需要基于TSC寄存器的时序?

  4. 即使在系统运行了一段时间后,来自/ proc/interrupts的IRQ8的值为cpu0提供1,为其他提供0.为什么只有一个来自IRQ8的中断,即实时时钟.

这不是一个功课问题

linux timer interrupt linux-kernel

4
推荐指数
1
解决办法
791
查看次数

标签 统计

linux ×2

linux-kernel ×2

time ×2

boost ×1

c ×1

c++ ×1

interrupt ×1

timer ×1

windows ×1