[英]std::chrono nanosecond timer works on MSVC but not GCC
I have a simple program that uses chrono
for timing that I had ported from MSVC to Code::Blocks.我有一个简单的程序,它使用
chrono
来进行我从 MSVC 移植到 Code::Blocks 的计时。 The display of the program shows the delta time from when it was started to 16 decimal places.程序的显示屏显示从它开始到小数点后 16 位的增量时间。 After getting it to compile, I noticed that the timer was only moving up from the first 6 decimal places.
编译后,我注意到计时器仅从小数点后 6 位开始向上移动。 The code remains unchanged, still using
std::chrono::high_resolution_clock::now();
代码保持不变,仍然使用
std::chrono::high_resolution_clock::now();
for the time, and then to calculate the delta time I use时间,然后计算我使用的增量时间
double localDeltaTime = std::chrono::duration_cast<std::chrono::nanoseconds>(m_EndTime - m_StartTime).count();
localDeltaTime = localDeltaTime / 1000000000.0;
This clearly displays nanosecond timings, yet GCC only seems to do microseconds?这清楚地显示了纳秒计时,但 GCC 似乎只做微秒? Is this a known issue?
这是一个已知的问题?
Here is an MRE,这是一个MRE,
#include <chrono>
#include <iostream>
#include <iomanip>
int main()
{
std::chrono::high_resolution_clock::time_point start = std::chrono::high_resolution_clock::now();
std::chrono::high_resolution_clock::time_point finish = start;
while (true)
{
finish = std::chrono::high_resolution_clock::now();
long double deltaTime = std::chrono::duration_cast<std::chrono::nanoseconds>(finish - start).count();
deltaTime /= 1000000000.0;
std::cout << std::setprecision(25) << deltaTime << std::endl;
}
return 0;
}
That's a known MinGW issue #5086 .这是一个已知的 MinGW 问题#5086 。
It mentions these possible workarounds:它提到了这些可能的解决方法:
std::chrono::steady_clock
std::chrono::steady_clock
QueryPerformanceCounter
Win32 APIQueryPerformanceCounter
Win32 API 构建自己的时钟Regarding MSVC:关于 MSVC:
First of all, on Windows, the best possible user-space timer resolution is 100 ns.首先,在 Windows 上,可能的最佳用户空间定时器分辨率为 100 ns。
In MSVC system_clock
and steady_clock
both support this resolution, so you should see 7 decimal digits changing.在 MSVC
system_clock
和steady_clock
都支持这个分辨率,所以你应该看到 7 个十进制数字在变化。
But writing to std::cout
takes a long time , on the order of 1 ms.但是写入
std::cout
需要很长时间,大约 1 毫秒。 So that's the reason why you're seeing large time steps in your version, you're essentially measuring std::cout
time.这就是为什么你在你的版本中看到大的时间步长的原因,你本质上是在测量
std::cout
时间。
I rewrote the test to print the minimum change in the time point:我重写了测试以打印时间点的最小变化:
#include <chrono>
#include <iostream>
#include <iomanip>
using namespace std::literals;
template<class Clock>
void runTest() {
std::cout << typeid(Clock).name() << '\n';
for (int i = 0; i < 5; i++) {
auto start = Clock::now();
for (;;) {
auto finish = Clock::now();
if (finish != start) {
std::cout << std::fixed << std::setprecision(9) << (finish - start) / 1.0s << '\n';
break;
}
}
}
}
int main() {
runTest<std::chrono::system_clock>();
runTest<std::chrono::steady_clock>();
runTest<std::chrono::high_resolution_clock>();
}
And here's the output I got:这是我得到的 output:
MSVC 19.28 (VS 2019): MSVC 19.28(VS 2019):
struct std::chrono::system_clock
0.000000200
0.000000100
0.000000100
0.000000100
0.000000100
struct std::chrono::steady_clock
0.000000100
0.000000100
0.000000100
0.000000200
0.000000100
struct std::chrono::steady_clock
0.000000200
0.000000100
0.000000100
0.000000100
0.000000100
MinGW-w64 GCC 10.2.0 (Rev1, Built by MSYS2 project): MinGW-w64 GCC 10.2.0(Rev1,由 MSYS2 项目构建):
NSt6chrono3_V212system_clockE
0.000999200
0.000998600
0.000999900
0.001000800
0.000999400
NSt6chrono3_V212steady_clockE
0.000000100
0.000000100
0.000000100
0.000000100
0.000000100
NSt6chrono3_V212system_clockE
0.000999900
0.001001900
0.001006200
0.001016600
0.000980700
So in case of MinGW we can see that at least steady_clock
provides 100 ns resolution, but unfortunately high_resolution_clock
is an alias of system_clock
.所以在 MinGW 的情况下,我们可以看到至少
steady_clock
提供 100 ns 的分辨率,但不幸的是high_resolution_clock
是system_clock
的别名。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.