问题描述
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的任何时间四舍五入到。这意味着您的循环只计算由于某种原因(计划,页面错误,缓存可能)比平均时间长的迭代。
由于每次测量的基本误差与测量的持续时间无关(加上其他误差),因此进行许多小测量并将它们相加会比一次测量整个持续时间精确得多。