以下程序在 centos 上的 gcc 4.6.2 下使用 -O3 编译:
#include <iostream>
#include <vector>
#include <algorithm>
#include <ctime>
using namespace std;
template <typename T>
class F {
public:
typedef void (T::*Func)();
F(Func f) : f_(f) {}
void operator()(T& t) {
(t.*f_)();
}
private:
Func f_;
};
struct X {
X() : x_(0) {}
void f(){
++x_;
}
int x_;
};
int main()
{
const int N = 100000000;
vector<X> xv(N);
auto begin = clock();
for_each (xv.begin(), xv.end(), F<X>(&X::f));
auto end = clock();
cout << end - begin << endl;
}
objdump -D
显示循环生成的代码是:
40097c: e8 57 fe ff ff callq 4007d8 <clock@plt>
400981: 49 89 c5 mov %rax,%r13
400984: 0f 1f 40 00 nopl 0x0(%rax)
400988: 48 89 ef mov %rbp,%rdi
40098b: 48 83 c5 04 add $0x4,%rbp
40098f: e8 8c ff ff ff callq 400920 <_ZN1X1fEv>
400994: 4c 39 e5 cmp %r12,%rbp
400997: 75 ef jne 400988 <main+0x48>
400999: e8 3a fe ff ff callq 4007d8 <clock@plt>
显然 gcc 没有内联该函数。为什么 gcc 不能进行这种优化?是否有任何编译器标志可以使 gcc 进行所需的优化?
我认为,GCC试图优化整体main
函数,但失败(大量间接调用全局函数来分配/释放内存xv
,获取定时器值、输入/输出等)。因此,您可以尝试将代码拆分为两个(或更多)独立的部分,如下所示:
inline
void foobar(vector<X>& xv)
{
for_each (xv.begin(), xv.end(), F<X>(&X::f));
}
int main()
{
const int N = 100000000;
vector<X> xv(N);
auto begin = clock();
foobar(xv);
auto end = clock();
cout << end - begin << endl;
}
所以,现在我们有了和以前一样的“等效”代码,但是 GCC 的优化器现在有更容易完成的任务。我没有看到任何电话ZN1X1fEv
现在在汇编程序列表中。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)