假设我们要在EDI中存储一个字符串。这样存储起来会更快吗

mov byte [edi],0
mov byte [edi+1],1
mov byte [edi+2],2
mov byte [edi+3],3
...


还是这种方式?

mov byte [edi],0
inc edi
mov byte [edi],1
inc edi
mov byte [edi],2
inc edi
mov byte [edi],3
inc edi
...


有人可能会在小尾数法中提出以下建议:

mov dword [edi],0x3210


或big-endian中的以下内容:

mov dword [edi],0x0123


但这不是我的问题。我的问题是,增加指针然后移动需要更多指令的速度更快,还是在每个mov指令中指定要添加到EDI指向的偏移地址的数量更快?如果后者是正确的,那么在将多少个具有相同编号的mov指令添加到偏移地址后,将其加到指针上就值得吗?换句话说,这是

mov byte [edi+5],0xFF
mov byte [edi+5],0xFF
mov byte [edi+5],0xFF
mov byte [edi+5],0xFF


比这快?

add edi,5
mov byte [edi],0xFF
mov byte [edi],0xFF
mov byte [edi],0xFF
mov byte [edi],0xFF

最佳答案

有关如何优化asm的文档,请参见http://agner.org/optimize/x86 Wiki中的其他链接。



这条路:

mov byte [edi],0
mov byte [edi+1],1
mov byte [edi+2],2
mov byte [edi+3],3
...


会更快。在当前的任何微体系结构AFAIK上使用位移都没有额外的成本,除了额外的一或四个字节的指令大小。 Two-register addressing modes can be slower on Intel SnB-family CPUs,但固定位移可以。

真正的编译器(例如gcc和clang)在展开循环时始终使用第一种方法(有效地址中的位移)。



顺便说一句,0x03020100的4字节存储几乎比四个单独的1字节存储快4倍。大多数现代CPU具有128b数据路径,因此,最多128b的任何单个存储都占用与8b存储相同的执行资源。 AVX 256b存储仍然比Intel SnB / IvB上的两个128b存储便宜,而Intel Haswell和更高版本可以在一次操作中完成256b存储。但是,立即移动到内存仅可用于8、16和32位操作数。 mov r64,imm64在64位模式下可用,但是没有128或256个mov-inmediate指令。



在32位模式下,可以使用一字节编码的inc reginc edi / mov byte [edi],1的代码大小相同,但是在最近的Intel和AMD微体系结构上,其解码量仍然是原来的两倍。如果代码仍然在商店吞吐量或其他方面成为瓶颈,那么这可能不是问题,但是没有更好的方法。 CPU非常复杂,通过计算uops进行的简单分析并不总是与您在实践中得到的结果相匹配,但是我认为每个存储之间的inc运行速度更快的可能性很小。您能说的最好的是它可能不会运行得很慢。它可能会使用更多的功率/热量,并且对超线程不太友好。

在64位模式下,inc rdx需要3个字节进行编码:1个REX指定64位操作数的大小(而不是默认的32位),1个操作码字节指定int r/m32,以及1个mod / rm字节将rdx指定为操作数。

因此,在64位模式下,存在代码大小的缺点。在这两种情况下,inc解决方案将在高度有价值的uop缓存中使用两倍的条目(在Intel SnB系列CPU上),该缓存保存了融合域uops。



第二部分:

mov byte [edi+5],0xFF
mov byte [edi+5],0xFF
mov byte [edi+5],0xFF
mov byte [edi+5],0xFF




add edi,5            ; 3 bytes to encode.  (2 if it was eax)
mov byte [edi],0xFF  ; saving one byte in each instruction
mov byte [edi],0xFF
mov byte [edi],0xFF
mov byte [edi],0xFF


除非代码大小非常重要(不太可能),或者存储更多,否则请使用第一种形式。第二种形式长一字节,但融合域uop少一字节。它将在拥有uop缓存的CPU上使用较少的空间。在较旧的CPU(没有uop缓存)上,指令解码更多是瓶颈,因此在某些情况下,将指令更好地排列为4组的情况就是瓶颈。但是,如果您在商店端口上遇到瓶颈,情况就不会如此。

08-07 14:39