- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
在 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.
您的案例可能利用了其中一个错误。简而言之:
注意事项:
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/
在循环遍历每种数据类型(整数、 double 、十进制和变量)的 100 万个随机数后,我试图测试数据类型之间的执行时间差异。我从 Microsoft Developer 网站获取了这段代码。我正在使
嘿,我正在使用 QueryPerformanceCounter 来计算该函数花费的时间(以毫秒为单位),但我收到了这个运行时错误: Run-Time Check Failure #2 - Stack
我正在使用 QueryPerformanceCounter 来测量某些函数/操作的时间。它曾经给我正确的数字,例如,我可以测试 Sleep(1000),它会返回非常接近 1 秒的时间。现在,它返回一个
我想使用 PerformanceCounter 来衡量执行某些操作需要多少时间。 我对 PerformanceCounter 和 C++ 了解不多。我在这里找到了一些代码: How to use Qu
我需要衡量我编写的函数的性能。由于我不能使用 C++11 并且我需要微秒,所以我使用了 windows.h 中的 QueryPerformanceCounter。 #include LARGE_IN
假设从 QueryPerformanceCounter 返回的计数是否安全?与上次系统启动后的时间有关?还是可以在系统运行时重置? MSDN 文章本身并不能保证这一点,但是我看到一些第 3 方信息(例
我正在使用 QueryPerformanceCounter 在我的应用程序中做一些计时。但是,在运行几天后,该应用程序似乎停止正常运行。如果我只是重新启动应用程序,它就会再次开始工作。这让我相信我的计
在 Windows 中通过分辨率较低的计时方法调用 QueryPerformanceCounter 是否会对性能产生影响? 最佳答案 虽然老了,this Dr Dobb's article很好地总结了
我正在考虑在两个同时处于事件状态的线程中重复调用(旋转)QueryPerformanceCounter。我不确定这是否真的是一个问题,因为我没有看到任何关于它的文章,但是 QueryPerforman
我创建了一个简单的程序来确定 QueryPerformanceCounter 调用需要多长时间。在我的计算机上大约需要 8 纳秒,但有时我会看到每次调用出现高达 500 微秒的峰值。 一些细节: Vi
在 linux 中是否有一个等效的 C 函数来读取 CPU 计数器及其频率? 我正在寻找类似于 QueryPerformanceCounter 函数的东西,它可以读取现代 CPU 中的 64 位计数器
嗨,我正在使用 QueryperformanceCounter 对 Delphi 中的一段代码进行计时。由于某种原因,我使用 QueryPerformanceCounter 得到的毫秒数与使用秒表得到
我需要使用 QueryPerformanceCounter Win32 API 格式化日期时间。格式为: HH:mm:ss.ffffff ,包含时分秒和微秒。我需要使用这个函数,因为另一个进程(用 C
#include "TIMER1.h" #include "MAIN.h" typedef unsigned _int64 uint64; void TASK1() { uint64 freq, s
我有一个等待 std::condition_variable 然后循环直到它完成的线程。 我试图滑动我在 opengl 中绘制的矩形。 在不使用 delta 的情况下一切正常,但我希望无论在哪台计算机
我想知道 Windows 函数 GetSystemTimePreciseAsFileTime 是否使用 QueryPerformanceCounter/RDTSC 计数器以亚微秒分辨率检索 UTC 时
我已经对这里找到的 PRIMATEs 密码做了一些切片实现:http://primates.ae/ (我用的是 120 位版本)。 我只用 C 语言制作并使用了 Intel Intrinsics,这样
我在 this post 中找到了有关使用 QueryPerformanceCounter 的有用信息但我面临一个我还没有找到答案的问题。 我正在为 Windows CE 6.0 开发一个应用程序,需
我正在研究在我们的系统中使用 QueryPerformanceCounter 的确切含义,并试图了解它对应用程序的影响。从我的 4 核单 CPU 机器上运行它可以看出,它需要大约 230ns 才能运行
鉴于 C# 中的 Stopwatch 类可以在下面使用类似三个不同计时器的东西,例如 系统定时器精度约为 +-10 ms,具体取决于可以使用 timeBeginPeriod 设置的计时器分辨率它可能约
我是一名优秀的程序员,十分优秀!