下面描述了指令选择优化.
一条 MMXTM指令可以具有两个寄存器操作数("OP reg,reg") 或一个寄存器操作数及一个内存操作数("OP reg, mem"). 在这里, OP代码指令操作数, reg代表寄存器, mem代表内存. "OP reg, mem" 指令在某些情况下是有用的, 因为它增加了每个时钟周期的操作数量, 减轻了对寄存器需要的压力, 并减少了代码长度.
下列讨论假设内存操作数位于数据高速缓存中的情况. 如果不是这样, 附加迟延通常增大, 使本节讨论的调度效果下降.
在奔腾处理器中, "OP reg, mem" 的 MMXTM指令的迟延不超过 "OP reg, reg" 指令(假设能命中 Cache). 但这种配对机会较为有限 (参见3.1节).在动态执行(P6-系列)处理器中, "OP reg, mem" 的 MMXTM指令, 将被转换为两条微操作 (与"OP reg, reg" 指令转为一条微操作相比). 因此, 它限制了译码的带宽 (参见(原书)2.1.2节), 并比"OP reg, reg"指令占用更多的资源.
推荐"OP reg, mem" 指令的用法是依据 MMXTM 代码是否受内存制约(即执行速度受内存访问限制). 由经验估计, 如果下列不等式成立, 则认为 MMXTM 代码受内存制约.
指令数 非 MMX 指令数 ------<内存访问数 + ------------- 2 2
对受内存制约的 MMXTM 代码, Intel 推荐对多次以上使用的同一内存地址的合并读取的方法, 它将减少内存访问的次数.
例:
OP MM0, [address A] OP MM1, [address A] 变成: MOVQ MM2,[address A] OP MM0,MM2 OP MM1,MM2
对不受内存制约的 MMXTM 代码, 仅在同一内存地址被使用两次以上时, 推荐使用合并读取. 在不能进行读取合并的地方, 推荐使用"OP reg,mem" 指令, 使代码长度和指令数最少.
例:
MOVQ MM0, [address A] OP MM1, MM0 变成: OP MM1, [address A]
在很多情况下, "MOVQ reg, reg" 和 "OP reg, mem" 可被 "MOVQ reg, mem" 和 "OP reg, reg" 代替. 由于它在动态执行处理器上节约一个微操作, 因此在可以使用的地方尽量使用:
例:(这里OP是对称操作)
MOVQ MM1, MM0 (1个微操作) OP MM1, [address A] (2个微操作) 变成: MOVQ MM1, [address A] (1个微操作) OP MM1, MM0 (1个微操作)
对奔腾处理器来说, 大于7字节的指令不能在 V管道中执行. 另外, 只有当两条指令的长度都小于等于7字节时, 才可都被压人指令的 FIFO(见(原书)2.1.1节).如果只有一条指令被压入FIFO, 则不能进行配对, 除非 FIFO中至少已有一条指令. 在配对可能性很高的代码中(在 MMXTM代码中常见), 或在末预测到分支后, FIFO可能为空, 此时任何时候长度超过7字节的指令将导致配对失败.
另外, 当指令超过7字节时, 动态执行(P6-系列) 处理器一次只能对一条指令译码.
因此, 为在所有的 Intel处理器上获得最佳性能, 使用简单的长度不超过8字节的指令 (参见4.1节一种减少指令长度的方法).