Dan*_*iel 2 c++ optimization c++11
为什么Clang 3.6不能为版本a和b以下程序生成相同的程序集?
#include <iostream>
#include <algorithm>
int main(int argc, char** argv)
{
std::cout << std::max(3, argc) << std::endl; // a
//std::cout << std::max({3, argc}) << std::endl; // b
return 0;
}
Run Code Online (Sandbox Code Playgroud)
编译-O3,组装的用于相关的比特a和b分别是:
##a
cmpl $2, %edi
movl $3, %esi
cmovgl %edi, %esi
movq __ZNSt3__14coutE@GOTPCREL(%rip), %rdi
##b
movq ___stack_chk_guard@GOTPCREL(%rip), %r15
movq (%r15), %r15
movq %r15, -32(%rbp)
leaq -40(%rbp), %rcx
movl $3, -40(%rbp)
leaq -36(%rbp), %rax
movl %edi, -36(%rbp)
movl $3, %esi
leaq -32(%rbp), %r8
movq %rcx, %rdx
jmp LBB0_1
.align 4, 0x90
LBB0_2:
movl (%rbx), %edi
movq %rax, %rcx
movq %rbx, %rax
LBB0_1:
cmpl %edi, %esi
cmovlq %rax, %rdx
movq %rcx, %rbx
addq $8, %rbx
cmpq %r8, %rbx
movl (%rdx), %esi
jne LBB0_2
movq __ZNSt3__14coutE@GOTPCREL(%rip), %rdi
Run Code Online (Sandbox Code Playgroud)
根据我对汇编的有限知识,看起来版本b已编译成std::max_element算法,这显然不如使用的算法有效a.为什么是这样?我们在使用时可以实际期望什么样的优化std::initializer_list?
您需要将您的clang升级到更高版本,因为有人显然发现了这种低效率并改进了它:
这是您的b示例现在生成的代码:
movl %edi, %eax
movl $3, (%rsp)
movl %eax, 4(%rsp)
cmpl $3, %eax
cmovlel (%rsp), %eax
Run Code Online (Sandbox Code Playgroud)
它不像原始示例那么整洁,但它比3.6编译器生成的代码更好.
与往常一样,编译器所做的优化很大程度上取决于"作者发现了什么,并找到了解决方案".第一步是"让它发挥作用".然后你看看它更快/更小.
我的铿锵版:
clang version 3.7.0
(http://llvm.org/git/clang.git 490122a3730b4ac7120ba9bee3e5dc51510d68d9)
(http://llvm.org/git/llvm.git 1c63fe6c61b2e1d6050f971f26946cda1e708a9c)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
182 次 |
| 最近记录: |