我有一个我正在测试的简单示例,我注意到当涉及 operator new 时,gcc 优化 (-O3) 似乎不如 clang 优化。我想知道可能是什么问题,是否可以强制 gcc 以某种方式生成更优化的代码?
template<typename T>
T* create() { return new T(); }
int main() {
auto result = 0;
for (auto i = 0; i < 1000000; ++i) {
result += (create<int>() != nullptr);
}
return result;
}
#clang3.6++ -O3 -s --std=c++11 test.cpp
#size a.out
text data bss dec hex filename
1324 616 8 1948 79c a.out
#time ./a.out
real 0m0.002s
user 0m0.001s
sys 0m0.000s
#gcc4.9 -O3 -s --std=c++11 test.cpp
#size a.out
text data bss dec hex filename
1484 624 8 2116 844 a.out
#time ./a.out
real 0m0.045s
user 0m0.035s
sys 0m0.009s
上面的例子只是我一开始测试的代码的一个简单版本, 但它仍然说明了 gcc/clang 之间的区别。 我也检查了汇编代码,在大小上没有太大差异,但在性能上肯定存在差异。另一方面,也许 clang 正在做一些不允许的事情?
最佳答案
如果我们将此代码插入 godbolt我们可以看到 clang
将代码优化为:
main: # @main
movl $1000000, %eax # imm = 0xF4240
ret
而 gcc
不执行此优化。所以问题是这是一个有效的优化吗?这是否遵循 draft C++ standard 中注明的 as-if 规则
1.9
程序执行部分说(强调我的):
The semantic descriptions in this International Standard define a parameterized nondeterministic abstract machine. This International Standard places no requirement on the structure of conforming implementations. In particular, they need not copy or emulate the structure of the abstract machine. Rather, conforming implementations are required to emulate (only) the observable behavior of the abstract machine as explained below.5
注释 5
说:
This provision is sometimes called the “as-if” rule, because an implementation is free to disregard any requirement of this International Standard as long as the result is as if the requirement had been obeyed, as far as can be determined from the observable behavior of the program. For instance, an actual implementation need not evaluate part of an expression if it can deduce that its value is not used and that no side effects affecting the observable behavior of the program are produced.
因为 new
可以抛出一个具有可观察行为的异常,因为它会改变程序的返回值。
R.MartinhoFernandes 认为,何时抛出异常是实现细节,因此 clang
可以决定这种情况不会导致异常,因此省略 new
调用会不违反 as-if 规则
。这对我来说似乎是一个合理的论点。
但作为 T.C.指出:
A replacement global operator new could have been defined in a different translation unit
Casey 提供了一个示例,表明即使 clang
发现有替代品,它仍然会执行此优化,即使有丢失的副作用。所以这似乎是过于激进的优化。
关于c++ - clang vs gcc - 优化包括 operator new,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25668420/