Assembly 80286:乘10最快的方法是什么?
要将一个数字乘以2的任意倍数,我将对它进行多次移位Assembly 80286:乘10最快的方法是什么?,assembly,x86-16,micro-optimization,Assembly,X86 16,Micro Optimization,要将一个数字乘以2的任意倍数,我将对它进行多次移位 有没有这样的技术可以在更短的周期内将一个数字乘以10 80286没有80386引入的桶形换档器。根据Microsoft Macro Assembler 5.0文档(1987)中的计时表,SHLreg,immed8需要5+n个周期,而SHLreg,1需要2个周期ADDreg,reg需要2个周期,MOVreg,reg也需要2个周期IMULreg16,immed需要21个周期。因此,乘以10的最快方法似乎是: ; /
有没有这样的技术可以在更短的周期内将一个数字乘以10 80286没有80386引入的桶形换档器。根据Microsoft Macro Assembler 5.0文档(1987)中的计时表,SHLreg,immed8需要5+n个周期,而SHLreg,1需要2个周期ADDreg,reg需要2个周期,MOVreg,reg也需要2个周期IMULreg16,immed需要21个周期。因此,乘以10的最快方法似乎是:
; // cycles
shl ax, 1 ; *2 // 2
mov bx, ax ; *2 // 4
shl ax, 1 ; *4 // 6
shl ax, 1 ; *8 // 8
add ax, bx ; *10 // 10
或者,或者:
; // cycles
mov bx, ax ; *1 // 2
shl ax, 1 ; *2 // 4
shl ax, 1 ; *4 // 6
add ax, bx ; *5 // 8
shl ax, 1 ; *10 // 10
无论哪种方式都有10个周期。特别是在80286上,因此可以使用即时移位,但
imul reg,reg,10
速度较慢,而且像lea ax、[eax+eax*4]
这样的32位寻址模式不便宜x*5
?您是否关心代码在任何更高或更早的CPU上的性能,以防286的最佳性能在其他地方不是最佳的?有80286指令计时的链接吗?Shift,add,Shift<代码>10*x=(4*x+x)*2=((x您可以将其保存在另一个寄存器中。mov bx,ax;shl ax,2;add ax,bx;shl ax,1
@ProjectZero:在286上,是的,很大程度上是的。即使在P5奔腾上,通过常量进行移位/加法而不是mul
的阈值至少是几个设定位;在现代Nehalem或更高版本上,10只有2个设定位。是比1操作数mul更好
,但并不比imul ax,bx,10(3周期延迟,1/时钟吞吐量,1 uop)好。我不确定移位和加法的比较,但你也可以通过四个加法来完成:mov bx,ax;add ax,ax;add ax,ax;add ax,bx;add ax ax,ax
。