arm's multiply(arm的乘)之一
arm's multiply
reference arm's an19
http://www.arm.com/pdfs/DAI0019D_ARM6_DSP.pdf
在做一些算法时常需要乘法运算,在ARMV4体系结构里都没有硬件乘法器,如何使乘法更有效率是本文的主题
在我的PDA(strongarm206)上开发一个jpegView的时候在做优化时发现了arm an19,看了一下,做了一下总结,该文中提出armcc(可能是ARM SDT的开发工具吧),会自动对乘法指令进行优化,但我在embed VC3中做的一个实验却发现并没有evc3并没有对ARM的乘法指令做优化.
1 overview
先介绍一下arm的指令周期,共4种,指令的执行时间长短除此以为还跟RAM的类型有关系
instruction times
s/n/i/c cycle
dram/sram
乘法的指令周期的估计
mul and mla instruction
2^(2n-3) <= t <= 2^(2n-1) -1MUL Rd,Rm,Rs
MLA Rd,Rm,Rs,Ra
所以需要1S+nI,例如第2个操作数是512以上时需要1S+6I共7个周期
so methods to improve speed
*place smallest operand in Rs
*ensure that Rs is positive so that early termination occurs
*if operand is a constant , use some special technique
优化时应考虑的方面:
*尽量使第2个操作数Rs最小
*确保Rs是正的,以使乘法迭代尽早完成,因为使用的是booth乘法器.
*如果操作数是常数,使用一些技巧
overflow
共32字长,是乘数和被数的位数和,所以可以是16X16,也可以是8X24
negative operands
如果Rs是负数的话,至少需要16I,而如果我们事先把操作数取反,则可出现提前终止
例如:
;
CMP Rs,#0
RSBMI Rs,Rs,#0
MUL Rd,Rm,Rs
RSBMI Rd,#0
被常数乘的分解
如果一个操作数是常数,例如105,则可有如下分解方法
A;
105=128-16+(2+1)
ADD Rd,Rm,Rm,LSL #1
SUB Rd,Rd,Rm,LSL #4
ADD Rd,Rd,Rm,LSL #7
B;
105=(16-1)*(8-1)
RSB Rt,Rm,Rm,LSL #4
RSB Rd,Rt,Rt, LSL #3
问题在于在常数很大时候,这种分解比较困难。