为了账号安全,请及时绑定邮箱和手机立即绑定

为什么clang用-O0产生低效率的asm(对于这个简单的浮点数总和)?

为什么clang用-O0产生低效率的asm(对于这个简单的浮点数总和)?

C
慕慕森 2019-09-26 15:02:29
为什么clang用-O0产生低效率的asm(对于这个简单的浮点数总和)?我正在llvm clang Apple LLVM版本8.0.0(clang-800.0.42.1)上反汇编以下代码:int main() {     float a=0.151234;     float b=0.2;     float c=a+b;     printf("%f", c);}我没有使用-O规范进行编译,但是我也尝试使用-O0(给出相同的值)和-O2(实际上是计算值并将其存储为预先计算的)产生的拆卸如下(我删除了不相关的零件)->  0x100000f30 <+0>:  pushq  %rbp    0x100000f31 <+1>:  movq   %rsp, %rbp    0x100000f34 <+4>:  subq   $0x10, %rsp    0x100000f38 <+8>:  leaq   0x6d(%rip), %rdi            0x100000f3f <+15>: movss  0x5d(%rip), %xmm0                0x100000f47 <+23>: movss  0x59(%rip), %xmm1             0x100000f4f <+31>: movss  %xmm1, -0x4(%rbp)       0x100000f54 <+36>: movss  %xmm0, -0x8(%rbp)     0x100000f59 <+41>: movss  -0x4(%rbp), %xmm0              0x100000f5e <+46>: addss  -0x8(%rbp), %xmm0    0x100000f63 <+51>: movss  %xmm0, -0xc(%rbp)     ...显然,它正在执行以下操作:将两个浮点数加载到寄存器xmm0和xmm1将它们放在堆栈中从堆栈中将一个值(不是xmm0之前的一个值)加载到xmm0执行添加。将结果存储回堆栈。我发现效率低下是因为:一切都可以在注册表中完成。我以后不会使用a和b,因此它可以跳过涉及堆栈的任何操作。即使它想使用堆栈,如果以不同的顺序执行操作,也可以节省从堆栈中重新加载xmm0的时间。考虑到编译器总是正确的,为什么选择这种策略?
查看完整描述

2 回答

?
ABOUTYOU

TA贡献1812条经验 获得超5个赞

请注意,至少clang实际上是从每个变量开始的,每个变量在堆栈上为其分配了内存。-O0如果可能的话,第一个优化过程之一(我想省略了)可以将它们变成一堆SSA变量。因此,至少在clang上,没有进行“反优化”,只是关闭了正常的优化。

查看完整回答
反对 回复 2019-09-26
  • 2 回答
  • 0 关注
  • 763 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信