更快的整数SSE未分配负载,很少使用

Z b*_*son 4 x86 sse intrinsics

我想更多地了解_mm_lddqu_si128内部(lddqu自SSE3以来的指令),特别是与_mm_loadu_si128内部(自SSE2以来的movdqu指令)相比.

_mm_lddqu_si128今天才发现.英特尔内在指南说

当数据穿过缓存行边界时,此内在函数可能比_mm_loadu_si128表现更好

评论说,

在某些情况下表现会更好,但从未表现得更差.

那么为什么它没有被更多地使用(SSE3是一个相当低的标准,因为所有的Core2处理器都有它)?为什么数据越过缓存线时性能会更好?是lddqu仅在处理器的某个子集可能更好.比如在Nehalem之前?

我意识到我可以阅读英特尔手册以找到答案,但我认为这个问题对其他人来说可能很有意思.

Pet*_*des 6

lddqu使用与movdquP4 不同的策略,但在支持它的所有其他CPU上运行相同.没有特别的缺点(因为SSE3指令不占用机器代码的任何额外字节,并且在这一点上甚至被AMD广泛支持),但除非你关心P4,否则没有任何优势.

Dark Shikari(负责大量SSE加速的x264视频编码器首席开发人员之一)在2008年的博客文章中详细介绍了它.这是一个archive.org链接,因为原版是离线的,但他的博客中有很多好东西.

他提出的最有趣的一点是,Core2仍然具有缓慢的未对齐负载,其中手动执行两个对齐的负载并且a palignr可以更快,但仅可用于立即移位计数.由于Core2运行lddqu相同movdqu,它没有帮助.

显然Core1确实是lddqu专门实现的,所以它毕竟不仅仅是P4.


这篇英特尔博客文章关于lddqu/movdqu的历史(我在2秒内发现google for lddqu vs movdqu,/ scold @Zboson)解释了:

(仅限P4):该指令通过加载在16字节边界上对齐的32字节块来工作,提取对应于未对齐访问的16字节.

因为指令加载的字节多于请求的字节数,所以适用一些使用限制 在Uncached(UC)和Write-Combining(USWC)内存区域应避免使用Lddqu.此外,通过其实现,在期望存储加载转发的情况下应该避免使用lddqu.

所以我想这就解释了为什么他们不只是一直使用这种策略来实施movdqu.

我猜解码器没有可用的内存类型信息,而且必须决​​定在哪些uop上解码指令.因此,即使是可取的,尝试在WB内存中使用更好的策略机会主义的"智能"也可能是不可能的.(这不是因为商店转发).


该博客文章的摘要:

从英特尔酷睿2品牌(Core微体系结构,从2006年中期开始,Merom CPU及更高版本)开始到未来:lddqu与movdqu做同样的事情

换句话说:
*如果CPU支持Supplemental Streaming SIMD Extensions 3(SSSE3) - > lddqu与movdqu做同样的事情,
*如果CPU不支持SSSE3但支持SSE3 - > go for lddqu(并注意关于内存的故事)类型)

  • @Zboson:基线只有SSE3而不是SSSE3并不比AMD特别伤害英特尔.它伤害了英特尔的客户,但我们仍然会购买他们的CPU.如果有的话,像这样的废话确实有利于英特尔,因为开发人员更有可能花时间为英特尔CPU实现加速,而不仅仅是AMD CPU.例如,甚至AMD已经放弃了未来CPU的XOP.(我希望英特尔采用它;'vpperm` 2源字节shuffle填补了这么多空白...)然后一些软件在Intel上比AMD更快,扩大了性能差距. (2认同)
  • 所以`lddqu`终于在AVX512中死了.`vpalignr`变成'valignr`并做正确的事.但是`vpsrldq/vpslldq`仍然会进行车道内换档.我很好奇这个用例是用于车道内128位移位.在这个阶段,它不再是"免费"来保持它.在Cannonlake的字节置换之前,它不是任何其他指令的子集.(虽然我认为如果你把'valign`硬件概括一点,它可以便宜地完成.) (2认同)