我正在对代码的性能至关重要的部分进行微优化,并遇到了指令序列(采用AT&T语法):add %rax, %rbxmov %rdx, %raxmov %rbx, %rdx我以为我终于有了一个用例xchg,可以允许我剃一条指令并编写:add %rbx, %raxxchg %rax, %rdx然而,令我感到困惑的是,我从Agner Fog的指令表中发现,这xchg是一条3微操作指令,在Sandy Bridge,Ivy Bridge,Broadwell,Haswell甚至Skylake上具有2个周期的延迟。3个完整的微操作和2个延迟周期!3个微操作会甩掉我的4-1-1-1节奏,最好的情况下2个周期的延迟使它比原始操作更糟,因为原始操作中的最后2条指令可能会并行执行。现在...我知道CPU可能正在将指令分解为等效于以下内容的微操作:mov %rax, %tmpmov %rdx, %raxmov %tmp, %rdx 这里tmp是一个匿名内部寄存器,我想最后两个微操作可以并行运行,因此延迟为2个周期。但是,鉴于寄存器重命名是在这些微体系结构上发生的,因此对我来说这样做是没有意义的。为什么寄存器重命名器不交换标签?从理论上讲,这将只有1个周期的延迟(可能为0?),并且可以表示为单个微操作,因此便宜得多。
3 回答
陪伴而非守候
TA贡献1757条经验 获得超8个赞
这似乎会使mul
每个时钟的吞吐量达到1 。我认为这mul/mulx r32
是3微妙而不是2微妙,这可能是因为它必须将乘法器输出的低64位分为上下半部分。但是我不确定这告诉我们什么mul r64
。我更倾向于内部缓冲理论;似乎不太可能mul r64
只通过转发网络发送上半部分,否则调度程序将不得不对乘法运算之间的耦合了解太多。
- 3 回答
- 0 关注
- 828 浏览
添加回答
举报
0/150
提交
取消