10

<chrono>我对C++ 11 中的新标头有几个问题。使用 Windows 7、Visual Studio 2012。

查看示例http://en.cppreference.com/w/cpp/chrono

#include <iostream>
#include <chrono>
#include <ctime>

int fibonacci(int n)
{
    if (n < 3) return 1;
    return fibonacci(n-1) + fibonacci(n-2);
}

int main()
{
    std::chrono::time_point<std::chrono::system_clock> start, end;
    start = std::chrono::system_clock::now();
    int result = fibonacci(42);
    end = std::chrono::system_clock::now();

    int elapsed_seconds = std::chrono::duration_cast<std::chrono::seconds>
                             (end-start).count();
    std::time_t end_time = std::chrono::system_clock::to_time_t(end);

    std::cout << "finished computation at " << std::ctime(&end_time)
              << "elapsed time: " << elapsed_seconds << "s\n";
}

可能的输出

finished computation at Sat Jun 16 20:42:57 2012
elapsed time: 3s
  1. 我注意到示例使用std::chrono::system_clock::now();是否意味着它只能用于测量经过的时间而不是 CPU 时间???如果我想测量 CPU 时间,我应该使用什么时钟?
  2. 请注意,elapsed time: 3s输出四舍五入为整数。有没有办法让它更颗粒化?
4

2 回答 2

15
  1. 正确的

    根据标准:

    system_clock 表示来自系统范围实时时钟的 [s] 挂钟时间。

    <chrono>库不提供测量 CPU 时间的机制,因此,如果您希望这样做,您将不得不依赖旧<ctime>库并使用std::clock().

    (如果你的目标是 Windows,你将不得不依赖 Windows 提供的任何特定于平台的 API 来获取 CPU 时间,因为正如你所指出的,它们std::clock()不能正常工作。)

    system_clock更像是 tostd::time()而不是 to的对应物std::clock()。(例如,请注意system_clock提供system_clock::time_points 和. 之间的转换time_t。)我认为缺少<chrono>用于测量 CPU 时间的时钟是由于标准委员会的时间限制以及该功能比系统的挂钟和真实时钟使用更少的事实-时钟。

    如果您想要 CPU 时间但也想要<chrono>提供的好处,您应该实现符合标准中概述的时钟概念并提供 CPU 时间的时钟类型,可能在内部使用std::clock().

  2. 说的那一行

    int elapsed_seconds = std::chrono::duration_cast<std::chrono::seconds>
                        (end-start).count();
    

    是导致时间四舍五入到整数秒的原因。您可以选择任何您想要的时间段,或者您可以使用浮点表示来允许非整数值:

    std::int64_t elapsed_attoseconds =
        std::chrono::duration_cast<std::chrono::duration<std::int64_t, std::atto>>
            (end-start).count();
    
    double elapsed_seconds =
        std::chrono::duration_cast<std::chrono::duration<double,std::ratio<1>>>
            (end-start).count();
    

    请注意,在实际代码中,您应该避免使用.count()来逃避由提供的强类型,chrono::duration直到您绝对必须。

    auto total_duration = end - start;
    auto seconds = std::chrono::duration_cast<std::chrono::seconds>(total_duration);
    auto milli = std::chrono::duration_cast<std::chrono::milliseconds>(total_duration - seconds);
    
    std::cout << seconds.count() << "s " << milli.count() << "ms\n";
    
于 2012-12-02T05:37:37.547 回答
4

1)我相当确定您可以获得的最高分辨率是使用std::chrono::high_resolution_clock然后不进行任何持续时间投射:

int elapsed_ticks = (end-start).count();

2) 将 duration_cast 的参数更改为nanoseconds

int elapsed_seconds = std::chrono::duration_cast<std::chrono::nanoseconds>
                             (end-start).count();
于 2012-12-02T04:21:05.050 回答