下述规则将帮助快速地开发出高效的MMX™代码,并且这些代码可以在具有MMX™技术的所有的处理器上运行。
3.1 规则列表及建议
以下给出一张规则和建议的列表。
3.1.1 规则
使用当前的编译器可以产生一个优化的应用程序。这将帮助你从一开始能产生好的代码。
避免部分寄存器的阻塞. 参见第3.2.4节。
注意分支预测算法(参见第3.2.5节)。这是动态执行(P6-系列)处理器最为重要的优化方法。由于提高了分支预测能力,你的代码将耗费很少的周期来读取指令。
对代码进行调度,使其达到最大的配对可能。参见第3.3节。
确定所有的数据都已对齐。参见第4.6节。
安排好代码,使其未命中的高速缓存指令最少,并优化预取。参见第3.5节。
不要混用MMX™指令和浮点指令。参见第4.3.1节。
避免使用除前缀为0F以外的操作码。参见第3.2.3节。
对同一个内存区域,避免在大数据量存贮数据后进行小数据量读取。或小数据量存贮后进行大数据量的读取。对于同一个内存区域,读取和存贮数据应使用同样大小的数据量;并且地址要对齐。参见第3.6.1节。
在任何时候,都要尽可能地使用OP,REG和MEM格式。这些格式可以帮助你减少占用寄存器,减少循环,避免产生不必要的读取操作。参见第3.4.1节。
EMMS必须放在MMX™指令的尾部。参见第4.4节。
优化高速缓存中的数据的带宽,以符合MMX™寄存器的大小。参见第3.6节。
3.1.2 建议
调整代码,一般情况下不使用向前条件分支,通常使用向后的条件分支。
按16字节边界条件对齐频繁执行的分支目标。
将循环展开来调度指令。
使用软件方式来安排流水线以调度迟延和功能单元。
必须成对使用CALL和 RET(return)指令。
避免使用自修改代码。
避免把数据放在代码段。
尽可能快地计算出存贮地址。
应避免使用包含三个或三个以上微操作代码或指令长度超过7个字节的指令。如果可能,使用只有一个微操作的指令。
不要使用两个8位读取指令来进行16位的读取。
在调用被调用保存(callee—save)过程前,先清除部分寄存器的内容。
解决阻塞条件,如存贮地址,尽可能地避免可能引起阻塞的读取。
一般情况下,一个可以直接由处理器支持的N-字节的数据(8位的字节,16值的字,32位的双字,32位、64位及80位浮点数)应该对齐在下一个最高的2的乘方边界处,避免未对齐的数据。
——按任意边界对齐8位数据。
——在已对齐的4-字节字数据内对齐16位数据。
——以4的任意倍数为边界,对齐32位数据。
——以8的任意倍数为边界,对齐64位数据。
——以128位为边界(即16字节的倍数),对齐80位数据。