Pentium 及 MMX 代码的优化

指令选择

[第三节调度][第五节:高速缓存优化]


   下面描述了指令选择优化.

4.1 使用访问内存的指令

  一条 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个微操作)

4.2 指令长度

  对奔腾处理器来说, 大于7字节的指令不能在 V管道中执行. 另外, 只有当两条指令的长度都小于等于7字节时, 才可都被压人指令的 FIFO(见(原书)2.1.1节).如果只有一条指令被压入FIFO, 则不能进行配对, 除非 FIFO中至少已有一条指令. 在配对可能性很高的代码中(在 MMXTM代码中常见), 或在末预测到分支后, FIFO可能为空, 此时任何时候长度超过7字节的指令将导致配对失败.

  另外, 当指令超过7字节时, 动态执行(P6-系列) 处理器一次只能对一条指令译码.

  因此, 为在所有的 Intel处理器上获得最佳性能, 使用简单的长度不超过8字节的指令 (参见4.1节一种减少指令长度的方法).


云风工作室 制作