【发布时间】:2017-11-28 15:58:05
【问题描述】:
考虑以下代码:
#include <algorithm>
#include <chrono>
#include <iostream>
#include <numeric>
#include <vector>
int main() {
std::vector<int> v(12);
std::iota(v.begin(), v.end(), 0);
//std::next_permutation(v.begin(), v.end());
using clock = std::chrono::high_resolution_clock;
clock c;
auto start = c.now();
unsigned long counter = 0;
do {
++counter;
} while (std::next_permutation(v.begin(), v.end()));
auto end = c.now();
auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);
std::cout << counter << " permutations took " << duration.count() / 1000.0f << " s";
}
在我的 AMD 4.1 GHz CPU 上使用 GCC (MinGW) 5.3 -O2 编译,这需要 2.3 s。但是,如果我在未注释的行中发表评论,它会减慢到 3.4 s。我期望最小的加速,因为我们测量的时间减少了一个排列。使用 -O3 时,2.0 s 与 2.4 s 之间的差异不那么极端。
谁能解释一下?超级智能的编译器能否检测到我想要遍历所有排列并优化这段代码?
【问题讨论】:
-
两次调用
next_permutation导致它没有被内联 -
您是否看到与 -O0 类似的行为?
-
Fwiw,Compiler Explorer 清楚地显示了 -O2 中缺少内联 - 请参阅 commented code 和 uncommented code。更奇怪的情况实际上是 -O3,其中所有调用都是内联的,但程序集的排列方式略有不同。为什么重新排序会产生更差的性能(根据 OP 的报告)尚不清楚。
-
@Serge no 和 -O0 都运行同样慢
-
谢谢,我觉得它很有教育意义。顺便说一句,我认为 -O3 没有任何区别。实际上,“慢”版本的运行速度比快速版本快几分之一秒 :-)。
标签: c++ performance function permutation compiler-optimization