c++ - clang vs gcc - 优化包括 operator new

标签 c++ gcc c++11 clang compiler-optimization

我有一个我正在测试的简单示例,我注意到当涉及 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 发现有替代品,它仍然会执行此优化,即使有丢失的副作用。所以这似乎是过于激进的优化。

请注意,memory leaks are not undefined behavior .

关于c++ - clang vs gcc - 优化包括 operator new,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25668420/

相关文章:

c++ - 在模板参数上使用隐式命名空间

c - 如何在 Linux 中抑制 -Werror=pointer-to-int-cast 和 -Werror=address 类型的错误

c++ - dlclose() 不适用于工厂函数和函数中的复杂静态?

c++ - 对象在 push_back 进入 vector 后立即销毁

c++ - 如何处理空参数包的情况

c++ - `int*[1]` 和 `int(*)[1]` 有什么区别?

c++ - Linux Pybind11 'build check -j 4' 错误

c++ - 函数调用中创建的对象和传入的对象有什么区别

c++ - 努力编写 C API 的线程安全 C++ 包装器

c++ - 在 Raspbian 上使用 C++ 线程,无法编译