简单for循环中的大量时间损失

问题描述

我有一个非常简单的程序来衡量一个函数花费了多少时间。

df2

输出确实令人困惑。以下是一些示例:

#include <iostream>
#include <vector>
#include <chrono>
struct Foo
{
    void addSample(uint64_t s)
    {
    }
};

void test(const std::vector<uint64_t>& samples)
{
    uint32_t onlyCallTime = 0;
    uint32_t loopOnlyTime = 0;
    Foo stats;
    std::chrono::high_resolution_clock::time_point callStart,callEnd;
    auto start = callStart = callEnd = std::chrono::high_resolution_clock::Now();
    for(auto &s : samples)
    {
        callStart = std::chrono::high_resolution_clock::Now();
        loopOnlyTime += std::chrono::duration_cast<std::chrono::microseconds>(callStart-callEnd).count();
        stats.addSample(s);
        callEnd = std::chrono::high_resolution_clock::Now();
        onlyCallTime += std::chrono::duration_cast<std::chrono::microseconds>(callEnd-callStart).count();
    }
    auto end = std::chrono::high_resolution_clock::Now();

    std::cout << "overall duration: " << std::chrono::duration_cast<std::chrono::microseconds>(end-start).count() << std::endl;
    std::cout << "only call duration: " << onlyCallTime << std::endl;
    std::cout << "only loop duration: " << loopOnlyTime << std::endl;
}

int main()
{
    std::vector<uint64_t> dataSetDecreasing;
    for(uint32_t i = 0; i < 1000000; ++i)
        dataSetDecreasing.push_back(1000000-i);
    test(dataSetDecreasing);
}
overall duration: 56047
only call duration: 195
only loop duration: 285
overall duration: 40984
only call duration: 177
only loop duration: 243

我看到overall duration: 47328 only call duration: 187 only loop duration: 177 捕获到callEnd-callStart + addSample的呼叫。
duration_cast捕获了其他所有内容,因此循环初始化,迭代,条件和第二个callStart-callEnd。我想念什么?其他的〜40000微秒又在哪里呢?

编译为duration_cast
g++ -Wall -Wextra -std=c++17 -O3
我的操作系统是Fedora 32版(三十二)

解决方法

1 000万次迭代花费了大约5万微秒。平均而言,每次迭代的时间要小于1μs, std::chrono::duration_cast<std::chrono::microseconds>会在小于1μs的任何时间四舍五入到。这意味着您的循环只计算由于某种原因(计划,页面错误,缓存可能)比平均时间长的迭代。

由于每次测量的基本误差与测量的持续时间无关(加上其他误差),因此进行许多小测量并将它们相加会比一次测量整个持续时间精确得多。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...