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

jav*_*red 30 c++ c++11 c++-chrono visual-studio-2012

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

#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;
}
Run Code Online (Sandbox Code Playgroud)

我机器上的输出:

分辨率(纳米)= 100

std :: cout需要多少纳秒?

std :: cout需要1000200纳秒

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

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

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

Dav*_*vid 53

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

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();
    };
Run Code Online (Sandbox Code Playgroud)

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));
}
Run Code Online (Sandbox Code Playgroud)

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

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

  • 这个问题[报告](https://connect.microsoft.com/VisualStudio/feedback/details/719443/)有一个错误,但还没有关于修复的消息 - 在此期间你总是可以使用boost. (8认同)
  • @javapowered他们这样做是因为他们认为他们拥有太多的市场份额并希望让人们不再使用VS. Visual Studio以多种方式糟透了,这是其中之一.以上是在VS的标准库中实现high_resolution_clock的方式......它也很简单,所以我不知道为什么他们只是去了`typedef`它到`system_clock`.也许它刚刚滑过裂缝. (4认同)
  • 有趣的是知道*VC++ 2012实现已经被MS的标准库维护者*认可为错误. - (http://stackoverflow.com/questions/13263277/difference-between-stdsystem-clock-and-stdsteady-clock) (4认同)
  • 使用Visual Studio 2015,`std :: chrono :: high_resolution_clock`现在是`typedef`到`std :: chrono :: steady_clock`.直接来自<chrono>`typedef steady_clock high_resolution_clock;` (4认同)
  • 要添加到Mark的注释 - steady_clock(以及扩展名high_resolution_clock),请使用VS2015中的QueryPerformanceCounter. (3认同)

bam*_*s53 6

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


high_resolution_clock几年来,Visual Studio的低分辨率一直是一个问题.微软的C++标准库维护者Stephan T. Lavavej 表示已经通过使用修复了VS2015 QueryPerformanceCounter().