为什么 sub 和 mul 指令的重新排序很有帮助?

问题描述 投票:0回答:1

这是来自《计算机系统:程序员的视角》的示例代码。

short foo(short a, short b) {
    short result;
    result = b;
    while(b > 0) {
        result *= a;
        b -= a;
    }
    return result;
}

使用

gcc14.2
-O1
-O3
进行编译,得到以下组件 (godbolt)

O1

foo:
        movl    %esi, %eax
        movl    %esi, %ecx
        testw   %si, %si
        jle     .L1
.L3:
        imull   %edi, %eax
        subl    %edi, %ecx
        testw   %cx, %cx
        jg      .L3
.L1:
        ret

O3

foo:
        movl    %esi, %eax
        movl    %esi, %edx
        testw   %si, %si
        jle     .L1
.L3:
        subl    %edi, %edx
        imull   %edi, %eax
        testw   %dx, %dx
        jg      .L3
.L1:
        ret

对于

O3
sub
位于
imul
之前 - 为什么这种重新排序有帮助?

  1. 我假设这与指令级并行性有关,但无法得到确切的原因。是不是先执行减法就可以用一些空闲的 ALU 来完成部分乘法?
  2. 就管道而言,这种重新排序有什么不同吗?
c assembly
1个回答
0
投票

正如您所注意到的,

subl
imul
可以并行执行(都不依赖于另一个),但是
testw
确实取决于
subl
的结果(理论上,是否使用下一个
imul
的结果取决于
testw
)因此,您想要完成并因此尽快开始
subl
,以便无论
testw
是否已完成,
imul
都可以开始.

© www.soinside.com 2019 - 2024. All rights reserved.