将数据放入 SIMD 寄存器需要多少个周期?

Posted

技术标签:

【中文标题】将数据放入 SIMD 寄存器需要多少个周期?【英文标题】:How many cycle does need for put a data into SIMD register? 【发布时间】:2013-12-18 01:37:18 【问题描述】:

我是一名学习 x86 和 ARM 架构的学生。

我想知道将多个数据放入 SIMD 寄存器需要多少个周期?

我了解 x86 SSE 的 xmms 寄存器有 128 位大小的寄存器。

如果我想通过 SIMD 指令集和汇编语言将 8 位数据中的 32 个放入堆栈中的 xmms 寄存器之一,该怎么办?

通用寄存器的 PUSH/POP 是否有相同的循环时间?

还是每 8 位数据需要 32 倍的时间?

感谢您的关心和关心!

【问题讨论】:

这取决于很多事情。 Agner Fog's tables 是一个很好的参考。但一般来说,你要避免做这种一对一的操作,因为它违背了 SIMD 的目的。 【参考方案1】:

简答:

如果您要执行多次重复的 128 位加载,则可以使用 Sandy Bridge、Ivy Bridge 和 Haswell 在每个时钟周期实现两次 128 位加载,或者使用 Nahelem 在每个时钟周期实现一次 128 位加载。 Nahelem 之前的处理器取决于您执行对齐加载还是未对齐加载。

长答案:

Mystical 在Agner Fog's Instruction Tables 为您提供了所需的信息。但让我为你(和我自己)拼写出来。

您要查看的指令是:MOVDQUMOVDQA,操作数为 x、m128。它们都将在一次操作中将 128 位数据加载到 XMM/YMM 寄存器中。 MOVDQA 要求地址按 16 字节对齐。 MOVDQU 没有这个限制。

您要查看的两个指标是延迟和互惠吞吐量(越低越好)。自 Nahelem 和 Sandy Bridge 以来,这些指标发生了两个重要变化:

    在 Nahelem 之前的英特尔处理器对于 MOVDQU 具有更高的延迟和倒数吞吐量。 但是,由于 Nahelem MOVDQUMOVDQA 具有相同的延迟和互惠的吞吐量。

    自 Sandy Bridge 以来的所有 Intel 处理器都可以同时执行两个 128 位加载。这可以在 intels-haswell-architecture 上很好地看到。您可以看到,在 Nahelem 中,只有端口 2 可以进行 128 位加载,而在 Sandy Bridge 和 Haswell(以及 Ivy Bridge)中,它们可以同时使用端口 2 和 3 进行两个 128 位加载(他们就是这样做的)一个 AVX 负载)。因此,Nahelem 的倒数吞吐量为 1,而 Sandy Bridge 的倒数吞吐量为 0.5。

但是,即使 MOVDQAMOVDQU 自 Nahelem 以来每个处理器具有相同的延迟和互惠吞吐量,但这并不意味着它们将提供相同的性能。如果地址不是 16 字节对齐的,则持久性可能会下降。您可以使用 ScottD 在Successful compilation of SSE instruction with qmake (but SSE2 is not recognized) 的代码对此进行测试,我的降幅约为 4%。我认为这是由于地址跨越缓存线的情况(例如,一个缓存线中的前 64 位和另一个中的下一个 64 位),否则性能是相同的。这实际上意味着自从 Nahelem 以来没有理由再使用MOVDQA。唯一的区别是内存对齐。


编辑: 我说Haswell可以同时做两个128位的加载。其实它可以同时做两个256-load。


编辑: 事实证明,使用 SSE 未对齐的加载指令不能用其他操作折叠。折叠允许CPU使用微操作融合(虽然这并不意味着它会融合但不折叠它肯定不会融合)。 因此,自 Nehalem 以来,对齐加载指令已过时的说法并不完全准确。更准确地说,它们已被 AVX 淘汰(与 Sandy Bridge for Intel 一起提供)。不过,实际上除了某些特殊情况外,不弃牌可能没什么区别。

【讨论】:

非常感谢!这才是我真正想知道的!我很高兴我学到了更多东西!谢谢!

以上是关于将数据放入 SIMD 寄存器需要多少个周期?的主要内容,如果未能解决你的问题,请参考以下文章

SIMD (AVX2) - 将 uint8_t 值加载到多个浮点 __m256 寄存器

使用 SIMD 指令去交错音频通道

基于布尔掩码将元素移动到 SIMD 寄存器的左侧

在同一个 SIMD 寄存器中串行添加值

armv8-a:测试 SIMD 寄存器是不是为 != 0

快速的寄存器内字节?