假设我们想在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
...
有些人可能会在little-endian中提出以下建议:
mov dword [edi],0x3210
或者big-endian中的以下内容:
mov dword [edi],0x0123
但这不是我的问题。我的问题是,增加指针然后执行mov需要更多指令是否更快,或者更快地在每个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
答案 0 :(得分:9)
有关如何优化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这样的真正的编译器在展开循环时总是使用第一种方法(有效地址中的位移)。
而BTW,0x03020100
的4字节存储将比四个单独的单字节存储快4倍。大多数现代CPU都有128b数据路径,因此任何高达128b的单个存储都需要与8b存储相同的执行资源。 AVX 256b商店仍然比英特尔SnB / IvB上的两个128b商店便宜,而英特尔Haswell和后来的商店可以在一次操作中实现256b商店。但是,mov-immediate到内存仅适用于8,16和32位操作数。 mov r64,imm64在64位模式下可用,但没有128或256个mov-immediate指令。
在32位模式下,inc reg
的单字节编码可用,inc edi
/ mov byte [edi],1
将具有相同的代码大小,但仍会解码为最近的两倍uop英特尔和AMD微体系结构。如果代码在商店吞吐量或其他方面仍然存在瓶颈,那么这个可能不会出现问题,但是没有办法让它变得更好。 CPU非常复杂,通过计算uops进行简单分析并不总是与实际结果相符,但我认为每个商店之间inc
运行更快的可能性极小。你能说的最好的是它可能运行得慢得多。它可能会使用更多的功率/热量,并且对于超线程不太友好。
在64位模式下,inc rdx
需要3个字节进行编码:1个REX指定64位操作数大小(而不是默认的32位),1个操作码字节指定int r/m32
,1个mod / rm字节指定rdx
作为操作数。
因此在64位模式下,存在代码大小的缺点。在这两种情况下,inc
解决方案将在高价值的uop-cache(在Intel SnB系列CPU上)使用两倍的条目,该缓存包含融合域uops。
第二部分:
mov byte [edi+5],0xFF
mov byte [edi+5],0xFF
mov byte [edi+5],0xFF
mov byte [edi+5],0xFF
VS
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少一个。它将在拥有它们的CPU上使用uop-cache中较少的空间。在较旧的CPU(没有uop缓存)上,指令解码更成为瓶颈,因此可能存在一些情况,其中指令更好地排列成4组是瓶颈。但是,如果你在商店港口遇到瓶颈,情况就不是这样了。