哪个更快。
add DWORD PTR [rbp-0x4],1
还是
mov eax,DWORD PTR [rbp-0x4]
add eax,1
mov DWORD PTR [rbp-0x4],eax
我已经看到了编译器生成的第二段代码,所以也许调用了 add
在一个寄存器上添加DWORD PTR更快?
它们都解码到了相同数量的后端uops,但是内存-目的地址 add
在现代的IntelAMD CPU上,通过前端以较少的融合域uops获取这些uops。
在英特尔CPU上。add [mem], imm
解码为一个微融合的load+add和一个微融合的store-address+store-data,所以前端总共有2个融合域的uops。 AMD CPU总是将内存操作数与ALU操作分组,而不称之为 "微融合",这只是他们一直以来的工作方式(https:/agner.orgoptimize 和 INC指令与ADD 1。这重要吗?).
第一种方式 不在寄存器中留值所以你不能把它作为一部分。++a
如果使用了该表达式的值。 只对内存的副作用。
使用 [rbp - 4]
而在内存中增量一个局部代码,听起来像是未经优化的调试模式代码,你应该 不 是在寻找什么是高效的。 优化后的代码通常使用 [rsp +- constant]
来寻址locals,并且(除非变量为 volatile
)不会是马上又把它存储回内存中。
为什么clang用-O0产生低效的asm(对于这种简单的浮点和)? - 在调试模式下编译,也就是 -O0
(默认值)分别编译每条C语句,并将每个变量视为类似于 volatile
,这是完全可怕的。
看 如何去除GCCclang汇编输出中的 "噪音"? 对于如何让编译器做出asm,很有意思。 编写一个函数,接受args并返回一个值,这样它就可以做一些事情,而不需要优化掉或将常量传播给 mov eax, constant_result
.
在寄存器中添加可能 是 更快(因为寄存器在芯片上),但是,由于你必须加载和存储数据,你不可能看到改进。
冗长的方法甚至可能是 较慢 因为CPU可能有机会优化较短的代码。此外,较短的代码 可 readmodifywrite有原子性,就看你怎么编码了。它当然不会浪费 eax
寄存器。
一句话,较长的代码不太可能有足够的改进(如果有的话)来证明可读性的影响。
但你不必猜测(甚至不必问我们)--芯片制造商提供了大量关于指令时序的细节。比如说 英特尔的优化手册.