Windows C++ 纳秒计时?

Posted

技术标签:

【中文标题】Windows C++ 纳秒计时?【英文标题】:Windows C++ nanosecond timing? 【发布时间】:2012-04-04 21:56:44 【问题描述】:

在 Windows 上的 C++ 中有没有办法以纳秒为单位测量时间?

我能找到的都是 linux 解决方案。

【问题讨论】:

见Boost.Chrono。 QueryPerformanceCounter 是 Windows,不过 Boost 也一样好,而且是可移植的。 在大多数系统上,您无法准确测量超出秒单位的执行时间。 如果你使用的是 VS11,你应该使用 chrono 库,并且你应该去支持 MS connect 上的this issue。 我非常怀疑您是否需要纳秒。这就像用 20 位数写下物理实验的结果一样。如果您使用纳秒,则必须注意每次内存访问,因为如果您完全随机,完整的缓存未命中可能会增加 30ns 的内存访问。 【参考方案1】:

使用 QueryPerformanceFrequency 函数查看 QueryPerformanceCounter 的运行速度。我认为它可能在纳秒范围内。

【讨论】:

非常旧的 API 调用,无法针对任务切换进行调整。 @Lothar:如果您以纳秒为单位测量执行时间,您会注意到何时发生任务切换,您可以跳过该测量示例。【参考方案2】:

查看 Windows 上的 QueryPerformanceCounter。

当定时代码识别性能瓶颈时,你想使用 系统必须提供的最高分辨率计时器。本文 描述了如何使用 QueryPerformanceCounter 函数来计时 申请代码

http://support.microsoft.com/kb/172338

【讨论】:

@Mehrdad:因为当我读到这篇文章时,我在理解问题的答案方面没有取得任何进展。这是一个链接。它应该有至少一个摘要。 @MooingDuck:这只是一个小答案。你确实有进步,因为现在你有资源可以去阅读。我完全希望答案的读者能够单击链接并阅读。总结可能不错,但这不是必需的,当然也不会将其作为评论。 (不行的是一个链接到后来可能会死掉的东西。) 一定不要点击链接,甚至懒得去阅读它的内容。这是一个总结。在对代码进行计时以识别性能瓶颈时,您希望使用系统必须提供的最高分辨率计时器。本文介绍如何使用 QueryPerformanceCounter 函数对应用程序代码进行计时。 @DanP:那应该是答案的一部分。 “正确”并不意味着某事是“好的答案”。链接很棒,但它们不是一切。 @MooingDuck:我认为点击链接和阅读文档是这个答案(正确)假设和/或试图教授的技能。【参考方案3】:

如果您可以运行自己的程序集,您可以读取 CPU 的周期计数器并将其除以 CPU 的时钟频率:

static inline uint64_t get_cycles()

  uint64_t t;
  __asm__ __volatile__ ("rdtsc" : "=A"(t));
  return t;

【讨论】:

IIRC,这可能有一个陷阱......它要么只在较新的 CPU 上可用,要么只在内核模式下可用,或者类似的东西...... @Mehrdad:rdtsc 从 P6 系列 CPU 开始可用,甚至可能是最初的 Pentium。它可以被限制在内核模式,但我不知道 Windows 是否这样做。 @Mehrdad:不,它不限于 Windows 上的内核模式。如果您使用 VC,则语法为 long long ticks() __asm rdtsc; 如果您所说的较新的 CPU 是指奔腾,是的,那么它仅适用于“较新”的 CPU。不过,就我个人而言,我已经有一段时间没有为 486 或更早版本编写代码了。 这里但是在多核上存在问题,因为返回的值不会在 CPU 或 CPU 核之间同步。但如果你只在单核/CPU 上运行,那就没问题了。 @Mehrdad:您还需要获取 CPU ID 并以某种方式管理 CPU ID 和滴答计数器的全局关联,但是当然,如​​果您想为跨 CPU 移动的操作计时'有麻烦了。但是,一个好的操作系统不应该这样做,因为它不想破坏热缓存。【参考方案4】:

使用 Windows7 和硬件计数器分析 API http://msdn.microsoft.com/en-us/library/windows/desktop/dd796395(v=vs.85).aspx

rdtsc 和 QueryPerformanceCounter/QueryPerformanceFrequency 都不够准确,因为开销大、中断和任务切换。

[编辑]:抱歉将 PerformanceCounter 的链接与硬件计数器混淆了。抱歉只使用过一次,这是一个快速的答案。

【讨论】:

如何使用它?我想不通。 如果你想比较不同代码实现的运行时间,计算使用执行周期而不是绝对时间。 @GManNickG:因为没有代码,没有描述,而且链接(过去时)完全没用。 @Lothar:实际上rdtscQueryPerformanceCounter(等)的问题(很可能QPC 是根据rdtsc 实现的)不在于开销,而是在跨 CPU 内核的同步中。每个核心都有自己的时间戳计数器,它们之间没有同步。 硬件计数器的好处还在于您可以使用它来测量 L1 和 L2 缓存未命中率。记住这一点很重要。

以上是关于Windows C++ 纳秒计时?的主要内容,如果未能解决你的问题,请参考以下文章

c++微秒级计时+对拍

使用 C++ 以纳秒为单位提供时间的计时器功能

C GetTickCount(windows函数)到时间(纳秒)

C++ / Qt 减少循环频率

在 Windows 中创建 C++ 非阻塞计时器

解决通信计时问题(C++ windows 应用程序)