挂钟时间通常由系统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()
甚至可以在微秒方案中显示粒度.但是:由于drift
TSC频率无法准确校正,因此对其准确性有严重的考虑.此外,在Linux中处理这个问题的代码的复杂性暗示着相信它实际上很难做到正确.这是特别的,但不仅仅是由Linux应该运行的大量硬件平台引起的.
结果: …
如何在Windows上获得微秒级分辨率时间戳?
我正在寻找比QueryPerformanceCounter
和更好的东西QueryPerformanceFrequency
(这些只能给你一个自启动以来经过的时间,并且如果在不同的线程上调用它们不一定准确 - 也就是说,QueryPerformanceCounter
可能在不同的CPU上返回不同的结果.还有一些处理器可以调整他们的节电频率,显然并不总是反映在他们的QueryPerformanceFrequency
结果中.)
有实现一个不断更新,高分辨率时间为Windows提供者,但它似乎并不稳固.当微秒问题看起来很棒,但它不能再下载了.
另一个资源是在Windows XP下获取准确的时间戳,但它需要许多步骤,运行辅助程序加上一些初始化的东西,我不确定它是否适用于多个CPU.
我还查看了维基百科文章时间戳计数器,它很有趣,但没那么有用.
如果答案只是用BSD或Linux来做,那就更容易了,这很好,但我想确认一下,并解释为什么在Windows中这么难以在Linux和BSD中这么容易.这是相同的精品硬件......
我仍然经常使用控制台输出来获取我的代码中发生的事情.我知道这可能有点老式,但我也用它来"管道"stdout到日志文件等.
但是,事实证明,由于某种原因,控制台的输出速度变慢了.我想知道是否有人可以解释为什么fprintf()到控制台窗口似乎有点阻塞.
到目前为止我做过/诊断过的事情:
我测量了fprintf(stdout,"quick fprintf\n");
它需要的时间
:0.82ms(平均值).由于vsprintf_s(...)
在几微秒内将相同的输出写入字符串,因此考虑的时间太长.因此,必须有一些专门针对控制台的阻止.
为了摆脱阻塞,我习惯vsprintf_s(...)
将输出复制到一个类似于fifo的数据结构中.数据结构受临界区对象的保护.然后,单独的线程通过将排队的输出放入控制台来对数据结构进行取消.
我可以通过引入管道服务获得进一步的改进.我的程序的输出(应该最终在控制台窗口中)按以下方式进行:
vsprintf_s(...)
将输出格式化为简单字符串.fprintf(stdout,...)
到控制台.所以我有两个进程,每个进程至少有两个线程,它们之间有一个命名管道,管道两侧有类似数据结构,以避免在管道缓冲区满时阻塞.
这是很多东西,以确保控制台输出是"非阻塞".但结果并不算太糟糕.我的主程序可以在几微秒内编写复杂的fprintf(stdout,...).
也许我之前应该问过:还有其他(更容易!)的方式来获得非阻塞控制台输出吗?
我正在阅读"了解Linux内核",其中有三个时钟
实时时钟
时间戳计数器(TSC)
可编程间隔定时器(PIT)
关于这些我几乎没有问题.
为什么计算机开机后不使用实时时钟?
系统运行时是否正在运行?
TSC寄存器使用PIT,那么为什么我们需要基于TSC寄存器的时序?
即使在系统运行了一段时间后,来自/ proc/interrupts的IRQ8的值为cpu0提供1,为其他提供0.为什么只有一个来自IRQ8的中断,即实时时钟.
这不是一个功课问题