【问题标题】:std::chrono nanosecond timer works on MSVC but not GCCstd::chrono 纳秒计时器适用于 MSVC 但不适用于 GCC
【发布时间】:2021-08-07 14:03:57
【问题描述】:

我有一个简单的程序,它使用chrono 来进行我从 MSVC 移植到 Code::Blocks 的计时。程序的显示屏显示从它开始到小数点后 16 位的增量时间。编译后,我注意到计时器仅从小数点后 6 位开始向上移动。代码不变,依然使用std::chrono::high_resolution_clock::now();的时间,然后计算我使用的delta时间

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;
}

【问题讨论】:

  • 您使用的是哪个版本的编译器以及使用哪个命令行?
  • @AlessandroTeruzzi 嗯,我也刚刚意识到,我更新了 Windows,这可能也更新了我的 Visual Studio 编译器。现在它们都只适用于微秒,GCC 和 MSVC,我以前在 1607,现在在 20h2。如何检查 Visual Studio 和 gcc 上的编译器?它也通过代码块,所以它没有编译命令行。
  • 哦,是的,MinGW32,我一直对这一切感到困惑。我对此有点陌生
  • 请注意,不能保证计时器具有纳秒级分辨率。在我工作过的盒子上,std::chrono::high_resolution_clock 通常具有 200 纳秒左右的基本分辨率。
  • 我什么都没做,但我认为可能是 Windows 更新搞砸了。在纳秒之前工作,现在不是。 - 至少对于视觉工作室。

标签: c++ gcc visual-c++


【解决方案1】:

这是一个已知的 MinGW 问题#5086

它提到了这些可能的解决方法:

关于 MSVC:

首先,在 Windows 上,最佳的用户空间计时器分辨率为 100 ns。

在 MSVC 中,system_clocksteady_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_clocksystem_clock 的别名。

【讨论】:

    猜你喜欢
    • 2022-11-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-12-08
    • 2013-12-25
    • 1970-01-01
    相关资源
    最近更新 更多