假设我们想在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或者大字号中的以下内容:
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发布于 2016-01-14 04:38:23
有关如何优化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上使用位移没有额外的成本,除了额外的一个或四个字节的指令大小。在Intel SnB系列CPUs上,双寄存器寻址模式可能会慢一些。,但是固定的位移很好。
像gcc和clang这样的实际编译器在展开循环时总是使用第一种方法(有效地址中的位移)。
0x03020100的4字节存储几乎比四个单独的单字节存储快4倍。大多数现代CPU都有128 B数据路径,因此任何高达128 B的存储都会占用与8b存储相同的执行资源。AVX256b存储仍然比英特尔SnB / IvB上的两个128 B存储便宜(如果对齐的话),而Intel和以后的存储可以在一次操作中完成256 b存储。然而,mov-立即到内存只对8,16和32位操作数可用.mov r64, imm64 (仅注册)在64位模式下可用,但没有128或256个mov即时指令.
在32位模式下,只要有inc reg的一字节编码,inc edi / mov byte [edi],1就会有相同的代码大小,但在最近的英特尔和AMD微体系结构上仍然可以解码到两倍多的uop。如果代码仍然在存储吞吐量或其他方面遇到瓶颈,这可能不是一个问题,但是没有更好的方法。CPU非常复杂,通过计算uops来进行简单的分析并不总是与您在实践中得到的结果相匹配,但我认为每个商店之间的inc运行速度是非常不可能的。你能说的最好的是,它的运行速度可能不会太慢。它可能会使用更多的电力/热量,并且对超线程不太友好。
在64位模式下,inc rdx需要3个字节来编码:1个REX指定64位操作数大小(而不是默认的32位),1个操作码字节指定inc r/m,1个mod/rm字节指定rdx作为操作数。
所以在64位模式下,有一个代码大小的缺点。在这两种情况下,inc解决方案将在高价值的uop缓存中使用两倍多的条目( Intel SnB-系列CPU),其中包含融合域uop。
更多的uop也意味着在ROB中有更多的空间,所以无序的高管看不到前面那么远。
此外,一条inc指令链将延迟存储地址uop更早地计算多个存储地址(并将它们写入存储缓冲区)。英特尔冰湖有两个端口,可以运行存储地址uop(从3个在哈斯韦尔)。如果较早地准备好存储地址,则对以后的加载更好,因此CPU可以确保它们是独立的,或者它们确实重叠。它还能让它们更早地脱离调度器(RS),释放出无序的exec结构中的空间。
第二部分:
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.
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组是瓶颈。不过,如果你在商店的港口遇到瓶颈,情况就不会是这样了。
https://stackoverflow.com/questions/34781387
复制相似问题