c++ 为什么来自计时库的高分辨率时钟以看似随机的顺序输出0和合理的值?

wlsrxk51  于 2023-03-20  发布在  其他
关注(0)|答案(1)|浏览(118)

我有一个函数,我正在使用计时库进行基准测试-有时输出为零的时间传递,有时一个更合理的值-在我的情况下约973,300纳秒。我想知道为什么这种行为发生具体-为什么有时输出为零,但有时973,300纳秒,我在上面提到过,我知道任何机器的精度都是有限制的,但是在时间0或其他更合理的时间有输出的事实是我所理解的。

#include <chrono>
#include <iostream>
using namespace std;

void megu()
{
    for(int i = 0; i < 1000000; i++);
}

int main()
{
    auto start = chrono::high_resolution_clock::now();
    megu();
    auto end = chrono::high_resolution_clock::now();
    auto duration = chrono::duration_cast<chrono::nanoseconds>(end - start);
    cout << duration.count();

    return 0;
}

我尝试用更长和更短的运行时函数运行代码(这里,函数megui较大,并且仅在较短的运行时间内发生。这表明这是一个精度问题-如果不是因为零之间输出的“合理”值具有低方差-它们之间的最大差异为20纳秒(在973以内,300纳秒窗口)。突然的零,那么,必须是由于其他的东西。我也尝试运行函数多次,以获得X数量的合理的值,以采取体面的平均值,我确实得到足够的这些合理的值,每次在一个单一的程序执行使用一个循环,丢弃0值(没有批处理文件等)。
我在Windows 11上,英特尔i7处理器。

2hh7jdfx

2hh7jdfx1#

你的编译器足够聪明,能够识别出megu中的循环什么也不做,因此这个函数调用被完全优化掉了。
您可以通过Compiler Explorer查看程序集来检查这一点。

megu():
  ret
main:
  pushq %rbx
  call std::chrono::_V2::system_clock::now()
  movq %rax, %rbx
  call std::chrono::_V2::system_clock::now()
  movl $_ZSt4cout, %edi
  subq %rbx, %rax
  movq %rax, %rsi
  call std::basic_ostream<char, std::char_traits<char> >& std::basic_ostream<char, std::char_traits<char> >::_M_insert<long>(long)
  xorl %eax, %eax
  popq %rbx
  ret

相关问题