Tho*_*mas 6 assembly cpu-registers
我有一个需要尽可能快的函数,它只使用整数运算.它运行在AMD64架构上,我需要做一些推/弹,以便有足够的寄存器来使用.现在我想知道,x64 ABI声明前四个浮点寄存器(XMM0,XMM1,XMM2和XMM3)是易失性的,不需要在函数调用之间保留.
所以我想我可以通过movq(MMX或SSE指令集)而不是使用堆栈来保存我需要保存在这些寄存器的低64位(即MM0,MM1,...)中的64位寄存器,从而节省了自己的工作.一些内存加载/存储.此外,我不需要使用EMMS来存储FPU状态 - 这会破坏目的 - 因为我实际上并没有操纵浮点寄存器而只是使用它们作为存储(而且无论如何,x87单元根本不使用x64,因为它基本上被SSE取代)
我已经做了修改并且它可以工作(没有崩溃,并且可观察到性能提高了4%),但是我想知道,这个"黑客"真的有用吗还是会引入我可能错过的任何特殊副作用(比如FPU状态)腐败,即使我不使用它,那种事情).加载/存储到FPU寄存器总是比任何当前架构上的内存加载/存储更快?
而且,是的,真的需要这种优化.公平地说,这不会严重降低代码维护成本,单行评论就足以解释这个伎俩.因此,如果我可以免费获得每个字节少的时钟而不会产生意想不到的后果,我很乐意接受它们:)
谢谢.
EMMS 指令仅需要在 MMX 操作后清除状态。SSE指令不需要它。所以这肯定不会冲突。
当然,您应该记住,不同的编译器和操作系统使用不同的调用约定,有些可能会以不同的方式对待这四个寄存器。
然而,只要牢记这一点,我认为这种方法没有问题。您正在按照 ABI 规定的方式使用所有寄存器。
假设这是用汇编语言编写的,则无需考虑这是否会阻碍编译器优化(深入 ASM 并开始讨论特定寄存器的 C/C++ 函数使编译器优化代码变得更加困难)