随后的两个std :: chrono :: high_resolution_clock :: now()相差约270ns

时间:2019-03-15 19:18:51

标签: c++ linux chrono

我想用一个std::chrono时钟来测量一段代码的持续时间,但是似乎无法测量持续几纳秒的时间。该程序:

#include <cstdio>
#include <chrono>

int main() {
    using clock = std::chrono::high_resolution_clock;

    // try several times
    for (int i = 0; i < 5; i++) {
        // two consequent now() here, one right after another without anything in between
        printf("%dns\n", (int)std::chrono::duration_cast<std::chrono::nanoseconds>(clock::now() - clock::now()).count());
    }
    return 0;
}

总是给我大约100-300ns。这是因为两个系统调用吗?是否可以减少两个now()之间的持续时间?谢谢!

环境:Linux Ubuntu 18.04,内核4.18,平均负载低,stdlib是动态链接的。

3 个答案:

答案 0 :(得分:2)

如果要测量非常快速的代码段的持续时间,通常最好将它们运行多次并取所有运行的平均时间,那么您提到的〜200ns可以忽略不计,因为它们分布在全部运行。

示例:

#include <cstdio>
#include <chrono>
using clock = std::chrono::high_resolution_clock;

auto start = clock::now();
int n = 10000; // adjust depending on the expected runtime of your code
for (unsigned int i = 0; i < n; ++i)
    functionYouWantToTime();
auto result =
    std::chrono::duration_cast<std::chrono::nanoseconds>(start - clock::now()).count() / n;

答案 1 :(得分:1)

使用rdtsc指令以最高分辨率和最少开销测量时间:

#include <iostream>
#include <cstdint>

int main() {
    uint64_t a = __builtin_ia32_rdtsc();
    uint64_t b = __builtin_ia32_rdtsc();
    std::cout << b - a << " cpu cycles\n";
}

输出:

19 cpu cycles

要将周期转换为纳秒,将周期除以以GHz为单位的基本CPU频率。例如,对于4.2GHz i7-7700k除以4.2。

TSC是CPU中所有内核共享的全局计数器。

现代CPU具有恒定的TSC,无论当前CPU的频率和升压如何,TSC的跳动速率均相同。在constant_tsc/proc/cpuinfo字段中查找flags

还请注意,__builtin_ia32_rdtsc比内联程序集更有效,请参见https://gcc.gnu.org/bugzilla/show_bug.cgi?id=48877

答案 2 :(得分:1)

请勿将时钟用于纳秒基准。取而代之的是使用CPU滴答声-在足够现代的任何硬件上,只要担心纳秒级,CPU滴答声都是单调的,稳定的并且在内核之间是同步的。

不幸的是,C ++没有公开CPU时钟,因此您必须直接使用RDTSC指令(可以将其很好地包装在内联函数中,也可以使用编译器的内在函数)。如果您愿意(通过使用CPU频率),CPU滴答的差异也可以转换为时间,但是通常对于这样的低延迟基准,没有必要。