提问者:小点点

std::chrono::high_resolution_clock的分辨率与测量值不对应


让我通过这个测试程序来问我的问题:

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

我的计算机上的输出:

分辨率(纳米)=100

std::cout需要多少纳秒?

std::cout耗时1000200纳秒

结果是收到(=1或2微秒。显然,要么的分辨率不是100纳秒,要么就是我测量的时间的方式是错误的。(为什么我从来没有收到1到2微秒之间的东西,例如

我需要一个高分辨率的C++定时器。操作系统本身提供了一个高分辨率的定时器,因为我能够在同一台机器上使用C#类以微秒精度测量事物。所以我只需要正确地使用操作系统的高分辨率定时器!

我如何修复我的程序以产生预期的结果?


共3个答案

匿名用户

我猜您使用的是Visual Studio2012。如果没有,就不要理会这个答案。Visual     Studio2012。可悲的是,这意味着它的精度很差(大约1 ms)。我编写了一个更好的高分辨率时钟,它使用在Visual&NBSPStudio&2012..中使用。

HighresClock.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:

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

(我省略了一个assert和。ifs,以查看是否正在Visual Studio 2012上根据上面的代码编译它。)

你可以在任何地方使用这个钟,使用方法和标准钟一样。

匿名用户

时钟的分辨率不一定与时钟使用的数据类型所能表示的最小持续时间相同。在这种情况下,您的实现使用的数据类型可以表示短至100纳秒的持续时间,但底层时钟实际上没有这样的分辨率。

Visual Studio的低分辨率问题已存在多年。MicrosoftC++标准库维护者Stephan T.Lavavej表示,在VisualStudio2015中已通过使用修复了这一问题。

匿名用户

也许实现没有实现更高分辨率的定时器?

您似乎使用的是Windows(您提到了C),因此,如果您使用的是计时器,并且您确实使用的是Windows,那么您可以使用QueryPerformanceRequency和QueryPerformanceCounter。