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

时间:2013-04-30 11:41:15

标签: c++ visual-studio-2012 c++11 chrono

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

#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 much nanoseconds std::cout takes?" << 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纳秒

我收到100020010003001000400100050010006002000600作为结果(= 1或2微秒) )。显然,std::chrono的分辨率 100纳秒,我衡量std::cout的时间是错误的。 (为什么我从未收到1到2微秒之间的东西,例如1500000?)

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

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

3 个答案:

答案 0 :(得分:51)

我猜你正在使用VS2012;如果没有,请忽略这个答案。 VS2012 typedef的{​​{1}}到high_resolution_clock。可悲的是,这意味着它具有糟糕的精度(大约1ms)。我写了一个更好的高分辨率时钟,使用system_clock在VS2012中使用...

<强> HighResClock.h:

QueryPerformanceCounter

<强> HighResClock.cpp:

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

(我遗漏了一个断言和#ifs,看看它是否在2012年从上面的代码编译)

您可以在任何地方以与标准时钟相同的方式使用此时钟。

答案 1 :(得分:5)

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


Visual Studio high_resolution_clock的低分辨率已成为问题多年。 Microsoft的C ++标准库维护者Stephan T. Lavavej,has indicated已通过使用QueryPerformanceCounter()在VS2015中修复了此问题。

答案 2 :(得分:1)

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

看来你正在使用Windows(你提到C#)所以如果你是一个计时器并且你确实在使用Windows,你可以使用QueryPerformanceFrequencyQueryPerformanceCounter