std::chrono提供了几个时钟来测量时间。同时,我想cpu唯一能计算时间的方法就是计算周期。
问题1:除了计算周期外,还有其他方法来评估时间吗?
如果是这样的话,因为计算机计数周期的方式永远不会像原子钟那样精确,这意味着计算机的“秒”(period = std::ratio<1>)实际上可以比实际的秒更短或更大,从而导致计算机时钟和全球定位系统之间在时间测量方面的长期差异。
问题2:是对的吗?
一些硬件有不同的频率(例如空闲模式和涡轮模式)。在这种情况下,这将意味着周期数将在一秒钟内发生变化。
问题3:是否是由cpu和cpu测量的“循环计数”,取决于硬件频率?如果是,那么std::chrono是如何处理它的?如果不是,周期对应于什么(比如什么是“基本”时间)?是否有一种在编译时访问转换的方法?是否有一种在运行时访问转换的方法?
发布于 2018-06-16 00:01:22
计数周期,是的,但是循环的什么
在现代x86上,内核使用的时间源(内部和clock_gettime及其他系统调用)通常是一个固定频率计数器,它计数“参考周期”,而不考虑涡轮、省电或停止时钟的空闲。(这是您从rdtsc或在C/C++中获得的计数器)。
普通的std::chrono实现将使用操作系统提供的函数,比如Unix上的clock_gettime。(在Linux上,这可以完全在用户空间、内核映射到每个进程的地址空间的VDSO页面中的代码+缩放因子数据中运行。低开销的时间资源很好。避免用户->内核->用户往返对于启用熔毁+谱缓解非常有帮助。
分析不受内存绑定的紧循环可能需要使用实际的核心时钟周期,因此它对当前核心的实际速度不敏感。(也不必担心将CPU提升到最大的涡轮,等等)例如使用perf stat ./a.out或perf record ./a.out。例如X86的MOV真的可以“免费”吗?为什么我不能复制这个?
有些系统没有/没有在CPU上内置一个与墙时钟相当的计数器,所以操作系统可以在RAM中维护一个时间,以便在计时器中断时进行更新,或者时间查询功能可以从一个单独的芯片读取时间。
(系统调用+硬件I/O =更高的开销,这是x86的rdtsc指令从分析对象转变为时钟源的部分原因。)
所有这些时钟频率最终都来自于mobo上的晶体振荡器。但是,可以调整从周期计数中推断时间的比例因素,以使时钟与原子时间保持同步,正如@Tony所指出的,通常使用网络时间协议(,NTP)。
发布于 2018-06-16 01:49:54
问题1:除了计算周期之外,cpu或gpu还有其他方法来评估时间吗?
不同的硬件可以提供不同的设施。例如,x86 PC已经使用了几个硬件设备来计时:在过去十年左右的时间里,x86 CPU让时间邮票柜位以它们的处理频率工作,或者--最近--一些固定频率(“恒定速率”,也就是“不变的”TSC);可能有一个高精度事件计时器,回到更远的地方有可编程中断定时器(计时)。
如果是这样的话,因为计算机计数周期的方式永远不会像原子钟那样精确,这意味着计算机的“秒”(周期= std::ratio<1>)实际上可以比实际的秒更短或更大,从而导致计算机时钟和全球定位系统之间的时间测量的长期差异。
是的,没有原子钟的计算机(它们现在可以使用在芯片上)不会像原子钟那样精确。也就是说,像网络时间协议这样的服务可以让你在一堆计算机上保持更紧密的一致性。它有时通过使用每秒脉冲(PPS)技术提供帮助。更现代和更精确的变体包括精确时间协议(PTP) (它通常可以在局域网内实现亚微秒精度)。
问题3: cpu和gpus测量的“循环计数”是否取决于硬件频率?
这要看情况了。对于TSC,较新的“恒定速率”TSC实现不会改变,其他实现也会有所不同。
如果是,那么std::with是如何处理它的?
我希望大多数实现都会调用操作系统提供的时间服务,因为操作系统往往对硬件有最好的了解和访问。有许多因素需要考虑--例如,TSC读数是否跨核同步,如果PC进入某种睡眠模式会发生什么情况,在TSC取样时需要什么样的记忆栅栏.
如果不是,周期对应于什么(比如什么是“基本”时间)?
有关英特尔CPU,请参见这个答案。
是否有一种在编译时访问转换的方法?是否有一种在运行时访问转换的方法?
std::chrono::duration::count公开了所使用的任何时间源的原始滴答计数,并且您可以将duraction_cast向其他时间单位(例如秒)公开。预计C++20将引入更多的工具,如clock_cast。AFAIK,没有可用的constexpr转换:如果一个程序在一台机器上运行的速率可能与编译它的机器不同,那似乎也是可疑的。
https://stackoverflow.com/questions/50883849
复制相似问题