我有兴趣在Windows中使用C++测量一个特定的时间点到纳秒.这可能吗?如果不是,是否有可能至少以微秒为单位获得特定时间?任何库都应该这样做,除非我认为托管代码是可能的.谢谢
And*_*nck 34
如果在多核计算机上运行的线程应用程序QueryPerformanceCounter
可以(并且将)根据代码执行的核心返回不同的值.请参阅 此 MSDN文章.(rdtsc
有同样的问题)
这不仅仅是一个理论问题; 我们用我们的应用程序遇到它并且必须得出结论,唯一可靠的时间源timeGetTime
只有ms精度(幸运的是在我们的情况下是足够的).我们还尝试为我们的线程修复线程亲和性,以保证每个线程始终从中获得一致的值QueryPerformanceCounter
,但是它确实有效,但它绝对杀死了应用程序中的性能.
总而言之,Windows上没有一个可靠的计时器,可用于以微秒精度计时(至少在多核计算机上运行时).
Kon*_*lph 14
Windows有一个高性能的计数器API.
您需要获取刻度形式QueryPerformanceCounter
并除以处理器的频率QueryPerformanceFrequency
.
LARGE_INTEGER frequency;
if (::QueryPerformanceFrequency(&frequency) == FALSE)
throw "foo";
LARGE_INTEGER start;
if (::QueryPerformanceCounter(&start) == FALSE)
throw "foo";
// Calculation.
LARGE_INTEGER end;
if (::QueryPerformanceCounter(&end) == FALSE)
throw "foo";
double interval = static_cast<double>(end.QuadPart - start.QuadPart) / frequency.QuadPart;
Run Code Online (Sandbox Code Playgroud)
这interval
应该是几秒钟.
小智 6
对于将来参考,对于Windows Vista,2008及更高版本,Windows需要硬件支持"HPET".它独立于CPU及其时钟和频率运行.有可能获得精度达到亚微秒的时间.
为了实现这一点,您需要使用QPC/QPF.问题是QPF(频率)是NOMINAL值,因此使用原始调用将导致时间漂移超过每天几分钟.为了达到这个目的,您必须测量实际频率并检查其随时间的漂移,因为热量和其他物理操作条件会影响它.
可以在此链接上的MSDN(大约2004年!)上找到描述此内容的文章. http://msdn.microsoft.com/en-us/magazine/cc163996.aspx
我自己实现了类似的东西(今天刚刚找到了上面的链接!)但是不想使用"微秒时间",因为与其他Windows调用(如GetSystemTimeAsFileTime)相比,QPC调用本身相当冗长,并且同步会增加更多开销.所以我更喜欢使用毫秒时间戳(比使用QPC少约70%的通话时间),特别是当我试图每秒钟数十万次时.
我认为微秒有点不合理(没有硬件帮助)。毫秒是可行的,但即使如此,由于各种邪恶的计数器分辨率问题,也不是那么准确。无论如何,我包括我自己的计时器类(基于 std::chrono)供您考虑:
#include <type_traits>
#include <chrono>
class Stopwatch final
{
public:
using elapsed_resolution = std::chrono::milliseconds;
Stopwatch()
{
Reset();
}
void Reset()
{
reset_time = clock.now();
}
elapsed_resolution Elapsed()
{
return std::chrono::duration_cast<elapsed_resolution>(clock.now() - reset_time);
}
private:
std::chrono::high_resolution_clock clock;
std::chrono::high_resolution_clock::time_point reset_time;
};
Run Code Online (Sandbox Code Playgroud)
请注意,在 Windows std::chrono::high_resolution_clock 上,底层使用的是 QueryPerformanceCounter,因此它是相同的但可移植。