繁体   English   中英

如何测量for循环的速度差异?

[英]How can I measure the speed difference of for loop?

我很好奇 for 循环中的以下项目。

  1. for(auto) 与 for(auto &)

  2. 分离for循环

  3. for(auto &) 与 for(const auto &)

  4. for(int: list) vs for(auto: list) [列表是 integer 向量]

因此,我编写了以下代码用于在 C++17 版本中进行测试。

CMake 调试模式似乎有所不同(未优化)

// In debug mode
1. elapsed: 7639 (1663305922550 - 1663305914911)
2. elapsed: 3841 (1663305926391 - 1663305922550)
3. elapsed: 3810 (1663305930201 - 1663305926391)

但是在release模式下(用gcc -O3)1~3没有区别

// release mode
1. elapsed: 0 (1663305408984 - 1663305408984)
2. elapsed: 0 (1663305409984 - 1663305409984)
3. elapsed: 0 (1663305410984 - 1663305410984)

不知道是我的测试方法不对,还是根据优化状态没有区别是正确的?

这是我的测试源代码。

// create test vector
const uint64_t max_ = 499999999;    // 499,999,999
std::vector<int>   v;
for (int i = 1; i < max_; i++)
    v.push_back(i);


// test 1.
auto start1 = getTick();
for (auto& e : v)
{
    auto t = e + 100;    t += 300;
}
for (auto& e : v)
{
    auto t = e + 200;    t += 300;
}
auto end1 = getTick();


// test 2.
// Omit tick function
for (auto& e : v)
{
    auto t1 = e + 100;    t1 += 300;
    auto t2 = e + 200;    t2 += 300;
}


// test 3.
for (auto e : v)
{
    auto t1 = e + 100;    t1 += 300;
    auto t2 = e + 200;    t2 += 300;
}

...

然后,通过chrono毫秒获得getTick()。

uint64_t getTick()
{
    return (duration_cast<milliseconds>(system_clock::now().time_since_epoch()).count());
}

此外,此测试在 Debian aarch64 上进行

  • Jetson Xavier NX(喷气背包 4.6,ubuntu 18.04LTS)
  • 8Gb 内存
  • GCC 7.5.0

如有不妥请指教。 谢谢!

一个空循环可以优化掉,所以你的编译器可以正确地做到这一点。 但是禁用优化的基准测试没有意义 C++ 需要优化以获得我们期望的生产使用性能(尤其是使用模板库函数),并且优化与否并不是一个常数因子加速; 它使表达相同逻辑的不同方式导致不同的asm,在通常优化的构建中,它们会编译为相同的asm。

您无法从调试版本中推断出发布版本中更快的内容,而不是像这样的小规模微优化。 另请参阅绩效评估的惯用方式?

启用优化后,如果您只使用该副本的一个成员,则复制到本地 object 可以删除大部分工作。 习惯于思考代码实际需要进行的实际工作; 编译器通常会找出最小值是多少。 例如, auto &实际上并不会将指针放入寄存器并取消引用它超出它首先循环数组所做的操作,引用变量实际上并不作为单独的存在于 asm 中的任何位置寄存器或 memory 中的值。

因此,如果没有循环中的一些实际工作(例如对数组求和或修改每个元素),这不是您可以在基准测试中隔离的东西。 您可以尝试使用Benchmark::DoNotOptimize或类似的内联 asm 来使编译器在不执行任何其他操作的情况下实现寄存器中的值,但要确保您的基准测试完全正确,您需要了解 asm 并检查编译器 output。 (微基准测试很难。)在这种情况下,您可能已经可以通过查看 asm 来回答这个问题,并且在正常情况下它是相同的。

在启用优化的情况下检查哪些东西都编译到相同的 asm 可能更容易,而不是试图猜测实验时间的微小差异是由于噪声还是可能是真正的差异。 (如果有区别,是否只是巧合,在这个特定的 CPU 上,代码 alignment 和周围代码的抽签速度更快。)

-O3模式将进行编译优化并删除代码。 您可以尝试在 for-loop 全局中声明变量以避免编译器优化。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM