gpt4 book ai didi

c++ - 为什么编译器会重复一些指令?

转载 作者:IT老高 更新时间:2023-10-28 13:22:51 36 4
gpt4 key购买 nike

有时编译器会生成带有奇怪指令重复的代码,这些重复指令可以安全地删除。考虑以下代码:

int gcd(unsigned x, unsigned y) {
return x == 0 ? y : gcd(y % x, x);
}

这是汇编代码(生成 by clang 5.0 并启用了优化):

gcd(unsigned int, unsigned int): # @gcd(unsigned int, unsigned int)
mov eax, esi
mov edx, edi
test edx, edx
je .LBB0_1
.LBB0_2: # =>This Inner Loop Header: Depth=1
mov ecx, edx
xor edx, edx
div ecx
test edx, edx
mov eax, ecx
jne .LBB0_2
mov eax, ecx
ret
.LBB0_1:
ret

在以下代码段中:

  mov eax, ecx
jne .LBB0_2
mov eax, ecx

如果没有发生跳转,eax 会无缘无故地重新分配。

另一个例子是函数末尾的两个 ret:一个也可以完美地工作。

是编译器不够智能还是有理由不删除重复项?

最佳答案

编译器可以执行人们不明显的优化,并且删除指令并不总是让事情变得更快。

少量搜索表明,当 RET 紧跟在条件分支之后时,各种 AMD 处理器都会出现分支预测问题。通过用本质上是无操作的内容填充该插槽,可以避免性能问题。

更新:

示例引用,“AMD64 处理器的软件优化指南”(参见 http://support.amd.com/TechDocs/25112.PDF)第 6.2 节说:

具体要避免以下两种情况:

  • 以单字节近返回 RET 指令为目标的任何类型的分支(条件或无条件)。请参阅“示例”。

  • 在代码中直接出现在单字节近返回 RET 指令之前的条件分支。

它还详细说明了为什么跳转目标应该对齐,这也可能解释了函数末尾的重复 RET。

关于c++ - 为什么编译器会重复一些指令?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48014076/

36 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com