【问题标题】:std::chrono::duration_cast - any unit more precise than nano-second?std::chrono::duration_cast - 比纳秒更精确的单位?
【发布时间】:2014-02-03 16:18:38
【问题描述】:

我想问一下,如何以任何单位计算时间,例如皮秒、飞秒以及更精确的时间。我正在计算函数的运行时间并使用纳秒,当我使用毫秒或纳秒时,函数的运行时间返回 0。我认为 Chrono 库只支持到纳秒,这是我在输入 chrono 后按 ctrl+space 时出现的最精确的::

int main()
{
    auto t1 = std::chrono::high_resolution_clock::now();
    f();
    auto t2 = std::chrono::high_resolution_clock::now();
    std::cout << "f() took "
              << std::chrono::duration_cast<std::chrono::milliseconds>(t2 - t1).count()
              << " milliseconds\n";
}

代码来源:http://en.cppreference.com/w/cpp/chrono/duration/duration_cast

谢谢。

【问题讨论】:

  • 尝试运行每个函数 1000 次或更多次,然后将结果时间除以 1000。还要注意,Windows 上的最大精度为 1 - 15 毫秒,具体取决于您的 Windows 是否喜欢您
  • @TheOne 如果运行该函数 1000 次需要 10 微秒,即 1 毫秒精度的时钟中的 0.01 毫秒,该怎么办?
  • @TheOne,这不是真的。 Windows 具有精度为 100 纳秒的高分辨率计时器。您必须使用 Windows API 来获取它们,但它们就在那里:msdn.microsoft.com/en-us/library/windows/desktop/…
  • Visual Studio 中的 不仅具有非常差的高分辨率时钟,而且还破坏了持续时间混合算术(这种完全不工作,因此显然从未测试过;由于某种原因,这些东西的成本高达 14,000 美元)。如果您必须使用 Visual Studio,我建议您使用 Boost.Chrono。
  • 我必须提交作业,老师的电脑是否也需要安装/设置boost库,因为它是外部库。

标签: c++ visual-c++ c++11


【解决方案1】:

您可以以更精确的持续时间(皮秒...)计算时间

www.stroustrup.com/C++11FAQ.html

见以下定义:

typedef ratio<1, 1000000000000> pico;

然后使用:

duration<double, pico> d{1.23}; //...1.23 picoseconds

更新 您的问题分为三个部分:

  1. 如何使用 std::chrono 并使用 std::chrono::duration 进行计算
  2. 如何获得更高精度的时间戳
  3. 如何对代码进行性能测试

上面我只回答了第一个问题(如何定义“皮秒”持续时间)。以下面的代码为例:

#include <chrono>
#include <iostream>
#include <typeinfo>

using namespace std;
using namespace std::chrono;

void f()
{
    enum { max_count = 10000 };
    cout << '|';
    for(volatile size_t count = 0; count != max_count; ++count)
    {
        if(!(count % (max_count / 10)))
            cout << '.';
    }
    cout << "|\n";
}

int main()
{
    typedef std::ratio<1l, 1000000000000l> pico;
    typedef duration<long long, pico> picoseconds;
    typedef std::ratio<1l, 1000000l> micro;
    typedef duration<long long, micro> microseconds;

    const auto t1 = high_resolution_clock::now();
    enum { number_of_test_cycles = 10 };
    for(size_t count = 0; count != number_of_test_cycles; ++count)
    {
        f();
    }
    const auto t2 = high_resolution_clock::now();
    cout << number_of_test_cycles << " times f() took:\n"
         << duration_cast<milliseconds>(t2 - t1).count() << " milliseconds\n"
         << duration_cast<microseconds>(t2 - t1).count() << " microseconds\n"
         << duration_cast<picoseconds>(t2 - t1).count() << " picoseconds\n";
}

它产生这个输出:

$ ./test
|..........|
|..........|
|..........|
|..........|
|..........|
|..........|
|..........|
|..........|
|..........|
|..........|
10 times f() took:
1 milliseconds
1084 microseconds
1084000000 picoseconds

如您所见,为了获得 1 毫秒的结果,我必须重复 f() 10 次。当您的计时器没有足够的精度时,重复您的测试是一般方法。有一个与重复相关的问题——重复你的测试 N 次并不需要花费成比例的时间。你需要先证明它。

另一件事 - 虽然我可以使用皮秒持续时间进行计算,但我的 high_resolution_timer 无法提供比微秒更高的精度。

要获得更高的精度,您可以使用时间戳计数器,请参阅 wiki/Time_Stamp_Counter - 但这很棘手且特定于平台。

【讨论】:

  • 我将如何使用它来复制我发布的代码中的功能,您能否指出我发布的代码,如何更改它以使其使用您拥有的方法描述。问候
【解决方案2】:

“标准”PC 的分辨率约为 100 纳秒,因此除非您拥有某种定制硬件,否则实际上不可能以高于该分辨率的分辨率测量时间。请参阅How precise is the internal clock of a modern PC? 了解相关问题并查看第二个答案:https://stackoverflow.com/a/2615977/1169863

【讨论】:

  • 可能是这样,但这不是重点。有时您必须对时间进行计算,并且希望最小化舍入误差的影响。因此,计算的精度远高于您的时钟支持的精度。
猜你喜欢
  • 2015-02-24
  • 1970-01-01
  • 2023-02-07
  • 1970-01-01
  • 1970-01-01
  • 2019-01-09
  • 2019-09-10
  • 2018-12-15
  • 1970-01-01
相关资源
最近更新 更多