我正在查看由GCC-4.8为x86_64生成的代码,想知道是否有更好(更快)的方法来计算三个值中的最小值。
这是Python的collections模块的摘录,该模块计算m
,rightindex+1
和leftindex
的最小值:
ssize_t m = n;
if (m > rightindex + 1)
m = rightindex + 1;
if (m > leftindex)
m = leftindex;
GCC使用CMOV生成与序列相关的代码:
leaq 1(%rbp), %rdx
cmpq %rsi, %rdx
cmovg %rsi, %rdx
cmpq %rbx, %rdx
cmovg %rbx, %rdx
是否有更快的代码可以通过消除数据依赖项来利用处理器无序并行执行的优势?我想知道是否有已知的技巧可以在不使用条件或谓词指令的情况下计算多个值的最小值。我还想知道是否存在一些饱和算术内在函数在这种情况下会有所帮助。
编辑:
最佳答案
至少两个无符号数具有经典的解决方案:
; eax = min(eax, ebx), ecx - scratch register.
.min2:
sub ebx, eax
sbb ecx, ecx
and ecx, ebx
add eax, ecx
这种方法可能比使用cmov的解决方案要快,但是为了获得更高的速度,指令必须与其他指令分开才能并行执行。
可以为三个数字实现此方法:
; eax = min(eax, ebx, edx), ecx - scratch register.
.min3:
sub ebx, eax
sbb ecx, ecx
and ecx, ebx
add eax, ecx
sub edx, eax
sbb ecx, ecx
and ecx, edx
add eax, ecx
另一种尝试是使用条件跳转来测试变体。对于现代处理器,它可能甚至更快,尤其是在高度可预测的情况下:
.min3:
cmp eax, ebx
jle @f
mov eax, ebx
@@:
cmp eax, edx
jle @f
mov eax, edx
@@: