Cec*_*ard 3 optimization x86 assembly x86-64 micro-optimization
在最近的高端Intel CPU上重新排序x64(x86-64)指令可以获得多少性能提升.在非常时间紧迫的情况下值得打扰吗?
我还想知道通过改变寄存器使用/使用额外的寄存器(如果空闲)来获得收益的可能性,以便在某些奇怪的情况下允许更长距离的代码移动?
指令调度在短距离内通常不是很重要,因为乱序执行通常是有效的.对于像某些ARM内核这样的有序CPU而言,这一点非常重要,因为在使用结果的指令之前调度负载是很重要的.
它可以帮助一些甚至在高端x86上,这取决于什么样的瓶颈限制了你的执行吞吐量.请参阅http://blog.stuffedcow.net/2013/05/measuring-rob-capacity/,了解有关ROB大小的一些有趣内容与物理寄存器数量是无序执行的限制因素. 软件流水线可以帮助实现无序执行难以隐藏的长依赖链.
尽早将指令放在关键路径依赖关系链上会有所帮助,因为OOO调度通常会尝试执行最早就绪的优先级.(请参阅如何安排x86 uops,确切地说?).
现代CPU是复杂的野兽,有时重新排序的东西可能会产生影响,当你不希望它重要.有时候无法准确猜出它为何会产生影响.不同的排序会影响解码器甚至uop缓存中的前端带宽,因为有许多规则关于uop缓存(在Intel CPU上)如何将解码的uop包装成最多6个uop线.例如,涉及Intel SnB系列CPU上的微编码指令的循环的分支对齐
有时解释非常模糊.例如,在英特尔的优化手册中,例3-25.重新排序序列以提高零延迟MOV指令的有效性,他们讨论立即覆盖零延迟-movzx结果以更快地释放内部资源.(我尝试了Haswell和Skylake的例子,并发现mov-elimination确实在更多的时候工作,但实际上它在整个周期中实际上稍微慢一点,而不是更快.示例旨在显示IvyBridge的好处,可能是其3个ALU端口的瓶颈,但HSW/SKL只是dep链中资源冲突的瓶颈,似乎不需要ALU端口来处理更多的movzx指令.)
可能这也适用于已删除的mov指令,不仅仅是movzx,但它可能不适用.
IDK如果我想知道如果我遇到真正的优化情况(对于IvyBridge),如果英特尔的手册没有用它作为一个例子.发布与执行的uops(融合域与未融合域)的性能计数器显示消除了多少个移动uop,但如果没有优化手册说明原因,几乎不可能找出它发生的原因.重新排序附近的独立指令只是为了尝试,可以作为调整的最后一步,但在那一点上它是伏都教/黑魔法/猜测.
正如玛格丽特指出的那样,除了简单的调度之外,还有理由对指令进行重新排序.有关详细信息,请参阅Agner Fog的优化和微体系结构指南以及x86标记wiki 中的其他资源.
例如,由于宏观融合,分组cmp/jcc和test/jcc一起总是一个好主意.编译时,编译器将为您执行此操作-march=haswell,因为它启用了-mtune=haswell.
如果它允许您避免某些mov指令或溢出/重新加载,它还可以打开其他优化机会,但这不仅仅是调度指令.