[英]Resolution of std::chrono::high_resolution_clock doesn't correspond to measurements
Let me ask my question by this test program:让我通过这个测试程序问我的问题:
#include <iostream>
#include <chrono>
using std::chrono::nanoseconds;
using std::chrono::duration_cast;
int main(int argc, char* argv[])
{
std::cout
<< "Resolution (nano) = "
<< (double) std::chrono::high_resolution_clock::period::num /
std::chrono::high_resolution_clock::period::den *
1000 * 1000 * 1000
<< std::endl;
auto t1 = std::chrono::high_resolution_clock::now();
std::cout << "How many nanoseconds does std::cout take?" << std::endl;
auto t2 = std::chrono::high_resolution_clock::now();
auto diff = t2-t1;
nanoseconds ns = duration_cast<nanoseconds>(diff);
std::cout << "std::cout takes " << ns.count() << " nanoseconds"
<< std::endl;
return 0;
}
Output on my machine:我机器上的输出:
Resolution (nano) = 100
分辨率(纳米)= 100
How many nanoseconds does std::cout take?
std::cout 需要多少纳秒?
std::cout takes 1000200 nanoseconds
std::cout 需要 1000200 纳秒
I receive either 1000200
or 1000300
or 1000400
or 1000500
or 1000600
or 2000600
as a result (= 1 or 2 microsecond).结果我收到
1000200
或1000300
或1000400
或1000500
或1000600
或2000600
(= 1 或 2 微秒)。 Obviously, either the resolution of std::chrono
is not 100 nano-seconds or the way I measure the time of std::cout
is wrong.显然,任分辨率
std::chrono
不100毫微秒或我的方式测量时std::cout
是错误的。 (Why do I never receive something between 1 and 2 microseconds, for example 1500000
?) (为什么我从来没有收到 1 到 2 微秒之间的信息,例如
1500000
?)
I need a high-resolution timer in C++.我需要一个 C++ 中的高分辨率计时器。 The OS itself provides a high-resolution timer, because I'm able to measure things with microsecond-precision using the C#
Stopwatch
class on the same machine.操作系统本身提供了一个高分辨率计时器,因为我能够在同一台机器上使用 C#
Stopwatch
类以微秒精度测量事物。 So I would just need to correctly use the high-resolution timer that the OS has!所以我只需要正确使用操作系统拥有的高分辨率计时器!
How do I fix my program to produce the expected results?如何修复我的程序以产生预期的结果?
I'm going to guess you are using Visual Studio 2012. If not, disregard this answer.我猜您正在使用 Visual Studio 2012。如果不是,请忽略此答案。 Visual Studio 2012
typedef
's high_resolution_clock
to system_clock
. Visual Studio 2012
typedef
的high_resolution_clock
到system_clock
。 Sadly, this means it has crappy precision (around 1 ms).可悲的是,这意味着它的精度很差(大约 1 毫秒)。 I wrote a better high-resolution clock which uses
QueryPerformanceCounter
for use in Visual Studio 2012...我写了一个更好的高分辨率时钟,它使用
QueryPerformanceCounter
在 Visual Studio 2012 中使用...
HighResClock.h:高分辨率时钟.h:
struct HighResClock
{
typedef long long rep;
typedef std::nano period;
typedef std::chrono::duration<rep, period> duration;
typedef std::chrono::time_point<HighResClock> time_point;
static const bool is_steady = true;
static time_point now();
};
HighResClock.cpp:高分辨率时钟.cpp:
namespace
{
const long long g_Frequency = []() -> long long
{
LARGE_INTEGER frequency;
QueryPerformanceFrequency(&frequency);
return frequency.QuadPart;
}();
}
HighResClock::time_point HighResClock::now()
{
LARGE_INTEGER count;
QueryPerformanceCounter(&count);
return time_point(duration(count.QuadPart * static_cast<rep>(period::den) / g_Frequency));
}
(I left out an assert and #ifs to see if it's being compiled on Visual Studio 2012 from the above code.) (我省略了断言和 #ifs 以查看它是否在 Visual Studio 2012 上从上述代码编译。)
You can use this clock anywhere and in the same way as standard clocks.您可以在任何地方以与标准时钟相同的方式使用此时钟。
The resolution of a clock is not necessarily the same as the smallest duration that can be represented by the data type the clock uses.时钟的分辨率不一定与时钟使用的数据类型可以表示的最小持续时间相同。 In this case your implementation uses a data type which can represent a duration as small as 100 nanoseconds, but the underlying clock doesn't actually have such a resolution.
在这种情况下,您的实现使用的数据类型可以表示小至 100 纳秒的持续时间,但底层时钟实际上没有这样的分辨率。
The low resolution of Visual Studio's high_resolution_clock
has been an issue for several years. Visual Studio 的
high_resolution_clock
低分辨率问题已经存在好几年了。 Microsoft's C++ standard library maintainer, Stephan T. Lavavej, has indicated that this has been fixed in Visual Studio 2015 via the use of QueryPerformanceCounter()
. Microsoft 的 C++ 标准库维护者 Stephan T. Lavavej 表示,这已通过使用
QueryPerformanceCounter()
在 Visual Studio 2015 中得到修复。
Maybe the implementation doesn't implement the higher resolution timer?也许实现没有实现更高分辨率的计时器?
It seems you are using Windows (you mention C#), so if you use a timer and you are indeed using Windows, you can use QueryPerformanceFrequency and QueryPerformanceCounter .看来您使用的是 Windows(您提到了 C#),因此如果您使用计时器并且您确实使用的是 Windows,则可以使用QueryPerformanceFrequency和QueryPerformanceCounter 。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.