我是一名学习 x86 和 ARM 架构的学生。
我想知道将多个数据放入 SIMD 寄存器需要多少个周期?
我知道 x86 SSE 的 xmms 寄存器有 128 位大小的寄存器。
如果我想通过 SIMD 指令集和汇编语言将 8 位数据中的 32 个放入堆栈中的一个 xmms 寄存器中,该怎么办,
通用寄存器的 PUSH/POP 是否具有相同的周期时间?
还是每 8 位数据需要 32 倍的时间?
感谢您的关注和关心!
最佳答案
简答:
如果您正在执行多次重复的 128 位加载,则可以使用 Sandy Bridge、Ivy Bridge 和 Haswell 实现每个时钟周期的 两个 128 位加载,或者使用 Nahelem 实现每个时钟周期的一个 128 位加载。 Nahelem 之前的处理器取决于您是执行对齐加载还是未对齐加载。
长答案:
Mystical 在 Agner Fog's Instruction Tables 为您提供了您需要的信息。但是让我为您(和我自己)详细说明。
你要查看的指令是:MOVDQU
和 MOVDQA
,操作数为 x、m128。它们都将在一次操作中将 128 位数据加载到 XMM/YMM 寄存器中。 MOVDQA
要求地址按 16 字节对齐。 MOVDQU
没有这样的限制。
您要查看的两个指标是 延迟和互惠吞吐量 (越低越好)。自 Nahelem 和 Sandy Bridge 以来,这些指标发生了两个重要变化:
MOVDQU
和 MOVDQA
具有相同的延迟和互惠吞吐量。 然而,即使
MOVDQA
和 MOVDQU
对于每个处理器具有相同的延迟和互惠吞吐量,这并不意味着它们会提供相同的性能。如果地址不是 16 字节对齐,则永久性可能会下降。你可以用 ScottD 在 Successful compilation of SSE instruction with qmake (but SSE2 is not recognized) 的代码测试这个,我得到了大约 4% 的下降。我认为这是由于地址跨越缓存行的情况(例如,一个缓存行中的前 64 位和另一个缓存行中的下一个 64 位),否则性能是相同的。这实际上意味着自 Nahelem 以来没有理由再使用 MOVDQA
。唯一的区别是内存对齐。编辑:
我说Haswell可以同时做两个128位的加载。事实上,它可以同时做两个 256 负载。
编辑:
事实证明,使用 SSE 未对齐的加载指令不能与另一个操作折叠。折叠允许CPU使用微操作融合(虽然这并不意味着它会融合但不折叠肯定不会融合)。
所以说对齐加载指令自 Nehalem 以来已经过时并不完全准确。更准确地说,它们已被 AVX 淘汰(随英特尔的 Sandy Bridge 一起提供)。但是,在实践中,除非在某些特殊情况下,否则不折叠可能没什么区别。
关于x86 - 将数据放入 SIMD 寄存器需要多少个周期?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20648158/