Rya*_*anS 18 performance x86 assembly pipeline
我最近一直在写x86程序集(为了好玩),并且想知道rep前缀字符串指令是否实际上在现代处理器上具有性能优势,或者它们是否刚刚实现了后向兼容性.
我理解为什么当处理器一次只运行一条指令时,英特尔最初会实现代表指令,但现在使用它们有什么好处?
通过循环可以编译更多指令,还有更多要填充管道和/或无序发布.现代处理器是为优化这些重复前缀指令而构建的,还是在现代代码中很少使用的rep指令,它们对制造商来说并不重要?
Fra*_*kH. 36
在AMD和英特尔的优化指南中,这样的问题都有很多空间.在这个领域给出的建议的有效性具有"半衰期" - 不同的CPU代表行为不同,例如:
在英特尔架构优化手册给出了不同的块复制技术(包括性能比较图rep stosd)上表7-2.内存复制例程的相对性能,pg.7-37f.,对于不同的CPU,再一次在其他CPU上最快的可能不是最快的.
在许多情况下,最近的x86 CPU(具有"字符串"SSE4.2操作)可以通过SIMD单元进行字符串操作,请参阅此调查.
要跟进所有这些(和/或当事情再次发生变化时保持自己更新,不可避免),请阅读Agner Fog的优化指南/博客.
除了FrankH的优秀答案; 我想指出哪种方法最好也取决于字符串的长度,它的对齐方式,以及长度是固定的还是可变的.
对于小字符串(可能高达大约16个字节),使用简单指令手动执行它可能更快,因为它避免了更复杂技术的设置成本(并且对于固定大小的字符串可以很容易地展开).对于中等大小的字符串(可能从16字节到4 KiB),类似"REP MOVSD"(如果可能出现未对准,则会引入一些"MOVSB"指令)可能是最好的.
对于任何大于此的东西,有些人会想要进入SSE/AVX和预取等.更好的想法是修复调用者,以便在第一次调用时不需要复制(或strlen()或其他)地点.如果你足够努力,你几乎总会找到一种方法.注意:也要非常警惕"假定的"快速mempcy()例程 - 通常它们已经在大量字符串上进行了测试,而不是在更可能的微小/小/中等字符串上进行测试.
还要注意(出于优化而不是方便的目的)由于所有这些差异(可能是长度,对齐,固定或可变大小,CPU类型等),为所有人提供一个多用途"memcpy()"的想法不同的情况是近视的.