我正在查看GCC-4.8为x86_64生成的代码,并想知道是否有更好(更快)的方法来计算三个值的最小值.
这是Python的集合模块的摘录,它计算m,rightindex 1和leftindex的最小值:
ssize_t m = n; if (m > rightindex + 1) m = rightindex + 1; if (m > leftindex) m = leftindex;
leaq 1(%rbp),%rdx cmpq %rsi,%rdx cmovg %rsi,%rdx cmpq %rbx,%rdx cmovg %rbx,%rdx
是否有更快的代码可以通过删除数据依赖性来利用处理器无序并行执行?我想知道是否存在用于计算多个值的最小值而不使用条件或谓词指令的已知技巧.我也想知道是否有一些饱和的算术内在函数可以帮助解决这种情况.
EDITS:
>如图所示,代码使用带符号算术,但无符号算术答案也有帮助.
>我问过最少三个,但也对n最小的n感兴趣.
> Linus对CMOV的警告:http://ondioline.org/mail/cmov-a-bad-idea-on-out-of-order-cpus
解决方法
最少两个无符号数具有经典解决方案:
; 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,ecx sub edx,edx add eax,ecx
另一种尝试是使用条件跳转来测试变体.对于现代处理器,它可能更快,特别是如果跳跃是高度可预测的:
.min3: cmp eax,ebx jle @f mov eax,ebx @@: cmp eax,edx jle @f mov eax,edx @@: