GJ.*_*GJ. 3 optimization assembly x86-64
在64位x86 CPU下,我们通常将数字-1加载到寄存器中,如:
mov rdx, -1 // 48BAFFFFFFFFFFFFFFFF
Run Code Online (Sandbox Code Playgroud)
...这个操作码需要10个字节.
另一种方式是:
xor rdx, rdx // 4831D2
dec rdx // 48FFCA
Run Code Online (Sandbox Code Playgroud)
...这个操作码只需要6个字节.
编辑:
正如JensBjörnhager所说(我已经测试过)xor edx, edx
操作码应该清除整个rdx寄存器:
xor edx, edx // 31D2
dec rdx // 48FFCA
Run Code Online (Sandbox Code Playgroud)
...这个操作码只需要5个字节.
编辑:
Alex找到另一个解决方案
mov rdx, -1 // 48C7C2FFFFFFFF
Run Code Online (Sandbox Code Playgroud)
...这个操作码只需要7个字节.但是如何告诉编译器使用更短的操作码(不使用DB)?
...
什么是更快,什么更经济?
它比所有提到的更短:4883CAFF OR rdx,-1
它具有对我所知道的所有架构具有错误依赖性的令人讨厌的特性,但它不应该被提及IMO.有合理的理由使用它.例如,如果直到很久之后才需要结果,并且它处于循环中,否则它将不适合四个16字节块.此外,如果速度对于特定代码片段并不是一个大问题,那么也不要浪费宝贵的缓存空间.它也可以用于对齐原因,但是填充到下一个更高的对齐几乎肯定会更快.
至于告诉编译器这个,我还没有得到线索.
第一个要好得多.第一个没有依赖关系.第二种具有最差的依赖性之一 - 指令在它开始之前需要紧接在它之前的指令的最终结果.但是,如果你有一些其他指令,你可以在xor
和之间滑动dec
,这将消除依赖性,然后第二个选项可能会胜出.
第二个也有错误依赖于rdx
第一个没有的值.一些CPU可能足够智能以识别这种错误依赖性并且不会使第一条指令停止,直到rdx
知道值为止(因为输出为零,无论如何).某些x86 CPU确实具有忽略某些错误依赖性的逻辑.
比较代码字节数并不是很有用.在大多数现实条件下,代码占用的字节数非常大.
还有另一种 7 字节编码mov rdx, -1
:48C7C2FFFFFFFF。
您可以尝试按照代码中的方式编写指令mov rdx, dword -1
,以帮助编译器/汇编器使用这种较短的编码。