gpt4 book ai didi

windows - Windows 10 下多核处理器上的 QueryPerformanceCounter 行为不稳定

转载 作者:可可西里 更新时间:2023-11-01 09:27:49 25 4
gpt4 key购买 nike

在 Windows 下,我的应用程序使用 QueryPerformanceCounter(和 QueryPerformanceFrequency)来执行“高分辨率”时间戳。

自 Windows 10 以来(目前仅在 Intel i7 处理器上进行了测试),我们观察到 QueryPerformanceCounter 返回值的不稳定行为。有时,调用返回的值会跳得很远,然后又回到它以前的值。感觉好像线程已经从一个核心移动到另一个核心,并且在一段时间内返回了不同的计数器值(没有证据,只是一种直觉)。

这在 XP 或 7 下从未观察到(没有有关 Vista、8 或 8.1 的数据)。

一个“简单”的解决方法是使用 BCDEdit 启用 UsePlatformClock 引导选项(这使得一切都正常运行)。

我知道可能更高级的 GetSystemTimePreciseAsFileTime,但由于我们仍然支持 7,所以这不是一个确切的选择,除非我们为不同的操作系统编写完全不同的代码,而我们真的不想这样做。

在 Windows 10 下是否观察到/解释了此类行为?

最佳答案

我需要更多关于您的代码的知识,但让我强调一些来自 MSDN 的内容:

When computing deltas, the values [from QueryPerformanceCounter] should be clamped to ensure that any bugs in the timing values do not cause crashes or unstable time-related computations.

尤其是这个:

Set that single thread to remain on a single processor by using the Windows API SetThreadAffinityMask ... While QueryPerformanceCounter and QueryPerformanceFrequency typically adjust for multiple processors, bugs in the BIOS or drivers may result in these routines returning different values as the thread moves from one processor to another. So, it's best to keep the thread on a single processor.

您的案例可能利用了其中一个错误。简而言之:

  • 您应该始终从一个线程查询时间戳(设置相同的 CPU 亲和性以确保它不会更改)并从任何其他线程读取该值(只是互锁读取,不需要花哨的同步)。
  • 限制计算出的增量(至少要确保它不是负数)...

注意事项:

QueryPerformanceCounter() 如果可能,使用 TSC(参见 MSDN )。同步 TSC 的算法(如果可用,在您的情况下应该是)从 Windows 7 到 Windows 8 发生了巨大变化,但请注意:

With the advent of multi-core/hyper-threaded CPUs, systems with multiple CPUs, and hibernating operating systems, the TSC cannot be relied upon to provide accurate results — unless great care is taken to correct the possible flaws: rate of tick and whether all cores (processors) have identical values in their time-keeping registers. There is no promise that the timestamp counters of multiple CPUs on a single motherboard will be synchronized. Therefore, a program can get reliable results only by limiting itself to run on one specific CPU.

然后,即使理论上 QPC 是单调的,您也必须始终从同一个线程调用它以确保这一点。

另一个注意事项:如果同步是由软件进行的,您可以从 Intel 文档中读到:

...It may be difficult for software to do this in a way than ensures that all logical processors will have the same value for the TSC at a given point in time...


编辑:如果您的应用程序是多线程的并且您不能(或者您不想)设置 CPU 亲和性(特别是如果您需要精确的时间戳,但代价是去-线程之间的同步值),那么您可以在 Win8(或更高版本)上运行时使用 GetSystemTimePreciseAsFileTime() 并回退到 Win7 的 timeGetTime()(将粒度设置为 1 毫秒后使用 timeBeginPeriod(1) 并假设 1 毫秒的分辨率就足够了)。一个非常有趣的阅读:The Windows Timestamp Project .

编辑 2:OP 直接建议!这在适用时(因为它是系统设置,而不是您的应用程序的本地设置)可能是一个简单的解决方法。您可以使用 bcdedit(参见 MSDN)强制 QPC 使用 HPET 而不是 TSC。延迟和分辨率应该更差,但本质上安全不会出现上述问题。

关于windows - Windows 10 下多核处理器上的 QueryPerformanceCounter 行为不稳定,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44020619/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com