我有一个简单的程序,它使用 chrono
进行计时,我已将其从 MSVC 移植到 Code::Blocks。程序的显示显示从启动时到小数点后 16 位的增量时间。编译后,我注意到计时器仅从前 6 位小数向上移动。代码保持不变,仍然使用 std::chrono::high_resolution_clock::now();
计算时间,然后计算我使用的增量时间
double localDeltaTime = std::chrono::duration_cast<std::chrono::nanoseconds>(m_EndTime - m_StartTime).count();
localDeltaTime = localDeltaTime / 1000000000.0;
这清楚地显示了纳秒计时,但 GCC 似乎只显示微秒?这是一个已知问题吗?
编辑:
这是 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;
}
最佳答案
这是一个已知的 MinGW 问题 #5086 .
它提到了这些可能的解决方法:
- 使用
std::chrono::steady_clock
- 使用Boost.chrono
- 构建your own clock使用
QueryPerformanceCounter
Win32 API
关于 MSVC:
首先,在 Windows 上,最佳的用户空间计时器分辨率是 100 ns。
在 MSVC 中,system_clock
和 steady_clock
都支持此分辨率,因此您应该看到 7 位十进制数字发生变化。
但是写入std::cout
需要很长的时间,大约为1毫秒。这就是您在版本中看到较大时间步长的原因,您实际上是在测量 std::cout
时间。
我重写了测试以打印时间点的最小变化:
#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>();
}
这是我得到的输出:
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,由 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
因此,在 MinGW 的情况下,我们可以看到至少 steady_clock
提供 100 ns 分辨率,但不幸的是 high_resolution_clock
是 system_clock
的别名。
关于c++ - std::chrono 纳秒计时器适用于 MSVC,但不适用于 GCC,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67584437/