具有直接 QueryPerformanceCounter 值的时钟可以符合 C++ 标准吗?
Posted
技术标签:
【中文标题】具有直接 QueryPerformanceCounter 值的时钟可以符合 C++ 标准吗?【英文标题】:Can Clock with direct QueryPerformanceCounter value be conforming to C++ Standard? 【发布时间】:2020-03-27 12:50:39 【问题描述】:假设我想用直接的QueryPerformanceCounter
Windows API 结果创建Clock
。 QueryPerformanceCounter
Windows API 返回一些计数器,该计数器应除以 QueryPerformanceFrequency
结果,从而产生以秒为单位的时间。
通常基于QueryPerformanceCounter
的Clock
会立即通过乘以某个句点并除以QueryPerformanceFrequency
将结果转换为某些单位。这就是 steady_clock
在 Windows 上的实现方式。
但假设出于性能原因,我想在真正需要之前避免分裂。所以time_point
是直接QueryPerformanceCounter
的值,而duration
是这样的区别。而且我大部分时间都可以对这些值进行算术和比较,仅将最终结果转换为一些正常的duration
或time_point
。
我相信这是可能的。我的问题是:这样的Clock
会完全兼容标准的Clock
。
【问题讨论】:
你的意思是named requirement Clock? 是的,时钟命名要求 据我了解,Clock
的唯一要求是@idclev463035818 已经解释过的......所以Clock
的概念就是满足这个要求。时间点可以是你想要的任何东西,它只需要表示从 epoch 传递了多少滴答声
我并没有真正解释它,但上面的链接确实列出了满足要求所需的所有内容,不是专家,但 afaik 它只是提供某些方法而不是is_steady
对语义的要求比较宽松
...所以,要回答您的问题,您必须出示您的代码。
【参考方案1】:
它不会与标准Clock Requirements 完全兼容。但它会编译并做你想做的事,大多数时候。不符合的部分是您必须为time_point
所基于的period
指定something。而且这不一定与物理时间单位相对应。
这无关紧要,除非您减去其中两个 time_points,得到 duration
,然后将 duration
与 确实代表物理时间的东西进行比较。然后你会得到运行时垃圾。
此外,如果您在sleep_until
或wait_until
中使用这样的time_point
,那么您的程序将不会休眠或等待预期的时间。
这是一个基于QueryPerformanceCounter
的计时时钟示例,它使用QueryPerformanceFrequency
确定物理单位:https://***.com/a/15755865/576911
【讨论】:
感谢您的回答。我正在考虑使period
完全合法的纳秒周期,但在rep
类型中隐藏系统特定的单元,因为它可能是a class emulating an arithmetic type
。还是不行吗?
所以当您的自定义rep
转换为标量时会发生物理时间的转换?可能会奏效。不确定。
我自己研究过这个问题,不,自定义rep
不起作用。但我原来的问题有解决方案。我已经添加了自己的答案。【参考方案2】:
正如 Howard Hinnant 解释的那样,重新定义的 time_point
和 duration
与编译时已知的 period
不对应的时钟不符合 Clock
要求。
使用模拟算术类型的类来隐藏额外的实现细节是行不通的。
由于标准没有定义什么是仿真,使用仿真类型的机会仅适用于标准实现提供的时钟。作为一个实践证明,std::chrono
和 boost::chrono
不能很好地与 boost::rational
配合使用。
然而,避免在每次查询中分割的一般任务至少有两个实际的解决方案。
第一个解决方案是遵循延迟除法直到需要的意图,但不重新定义time_point
和duration
。定义符合标准的时钟,并作为扩展定义原始时间戳的接口。所以,clock 可能有raw_now()
方法,返回raw_time_point
类型,这样的区别是raw_duration
类型。 raw_time_point
可以隐式转换为 time_point
和 raw_duration
到 duration
。
第二种解决方案是为每次查询计算符合标准的time_point
,但使用libdivide 库进行快速除法而不进行除法运算。
该库采用除数并对其进行处理,以便使用已处理除数的每个除法都使用快速操作完成。当然,处理除数需要时间,但对于相同除数的重复除法,它是一次性开销。所以这个库看起来是这个任务的理想匹配。 (请注意,该库对于编译时已知的常量没有用,因为在这种情况下编译器会避免自行除法,但QueryPerformanceFrequency
结果是运行时常量)。
【讨论】:
以上是关于具有直接 QueryPerformanceCounter 值的时钟可以符合 C++ 标准吗?的主要内容,如果未能解决你的问题,请参考以下文章
Pod具有未绑定的直接PersistentVolumeClaims
Google Pub/Sub 功能是不是具有在上传后直接通知 Google App Engine 端点的某些功能?