由汇编内核的MD5算法编写谈代码优化
2010-06-23 20:41:03 来源:WEB开发网3.2 单句的优化
现在我们首先将上叙C代码用最简单朴实的思路转换成为汇编,其中ROTATE_LEFT(x, n)实际上是一个循环左移,可以替换成为 ROL,加减乘除也可以用汇编相应的代码来替换,开始要注意的是,考虑到中间的一些参数,比如x,a要反复利用,我们必须把结果用临时变量来保存,单句的优化如下:
//参考test/test2的原代码
#define FF(a, b, c, d, x, s, ac)
__asm mov tmp1,b
__asm and tmp1,c
__asm mov tmp2,b
__asm not tmp2
__asm and tmp2,d
__asm or tmp2,tmp1 <- 以上为F(x, y, z)实现
__asm add tmp2,x
__asm add tmp2,ac
__asm add a,tmp2
__asm rol a,s <- (a) = ROTATE_LEFT(x, n)
__asm add a,b <- (a) += (b)
<- 以上为FF(a, b, c, d, x, s, ac)实现
3.3 多句的整合优化
上面的代码已经从23行下降到了11行,是不是到了极限了呢。还没有,我们还可以作一些汇编行与行之间的优化,注意:
__asm add tmp2,ac
此处,我们可以采取连加的语句来实现,大家可能回感到奇怪,汇编中有连加的语句吗,好像没有听说过啊,其实此处优化我们利用的是语句lea,大家看看下面的lea语句:
__asm add a,tmp2
__asm lea a,[tmp2+a+ac]
lea的标准用法是:
LEA REG,[BASE+INDEX*SCALE+DISP]
其实这种寻址方式常常用于数据结构中访问特定元素内的一个字段,base为数组的起始地址,scale为每个元素的大小,index为下标。如果数组元素始数据结构,则disp为具体字段在结构中的位移。此处我们是将scale设置为1,所以就变成了:
LEA REG,[BASE+INDEX +DISP]
因此就实现了三个数字的连加,类似的优化方法还有不少
所以再次优化后如下共10句:
//参考test/test3的原代码
3.4 利用mmx指令优化
#define FF(a, b, c, d, x, s, ac)
__asm mov tmp1,b
__asm and tmp1,c
__asm mov tmp2,b
__asm not tmp2
__asm and tmp2,d
__asm or tmp2,tmp1
__asm lea a,[tmp2+a+ac]
__asm add a,x
__asm rol a,s
__asm add a,b
我的这几个工程虽然没有涉及到利用mmx指令优化,但是我们考虑到mmx指令是基于64位的,可以大大的减少运算量,最明显的例子是des算法,它加密的明文是64位,加密后的密文也是64位,所以使用mmx的寄存器mm0,mm1,……,可以得到性能的提升,不过要注意如何尽可能的满足U,V流水线的需求,就不在本文的讨论范围内了。有兴趣的可以参考下面的地址:
http://www.chinaithero.com/dev/mmx/mmx.htm
我暂时能够想到的就是这些了,我在确实感到程序优化所带来的系统性能提升那种快感是无可比拟的,我2002年10月开始写的时候,一个8位数的穷举破解花了8个小时,到了2003年1月,时间只有4分钟,可见优化对一个运算密集型的软件是多么的重要。
本文配套源码
更多精彩
赞助商链接