我是学习x86和ARM架构的学生。
我想知道将多个数据放入SIMD寄存器需要多少个周期?
据我所知,x86 SSE的xmms寄存器具有128位寄存器大小。
如果我想通过SIMD指令集和汇编语言将32位8位数据从堆栈中放入xmms寄存器中,
对于通用寄存器的PUSH / POP具有相同的循环时间吗?
或每8bit数据需要32倍的时间吗?
感谢您的关注和关注!
答案 0 :(得分:13)
简答:
如果您正在进行多次重复的128位负载,则可以使用Sandy Bridge,Ivy Bridge和Haswell在每个时钟周期实现两个128位负载,或者使用Nahelem <每个时钟周期一个128位负载< / strong>即可。 Nahelem之前的处理器取决于您是否进行了对齐加载或未对齐加载。
答案很长:
Mystical在Agner Fog's Instruction Tables为您提供了所需的信息。但是,让我为你(和我自己)拼出来。
您要查看的说明是:MOVDQU
和MOVDQA
,操作数为x,m128。这两者都将在一次操作中将128位数据加载到XMM / YMM寄存器中。 MOVDQA
要求地址按16字节对齐。 MOVDQU
没有这样的限制。
您要查看的两个指标是延迟和互惠吞吐量(越低越好)。自Nahelem和Sandy Bridge以来,这些指标发生了两个重要变化:
Nahelem之前的英特尔处理器具有更高的延迟和MOVDQU的相应吞吐量。 但是,由于Nahelem MOVDQU
和MOVDQA
具有相同的延迟和相应的吞吐量。
自Sandy Bridge以来的所有英特尔处理器可以同时执行两个128位加载。这可以在intels-haswell-architecture很好地看到。您可以看到,在Nahelem中,只有端口2可以执行128位负载,而在Sandy Bridge和Haswell(和Ivy Bridge)中,它们可以同时使用端口2和3执行两个128位负载(这是他们的工作方式)一个AVX负载)。因此,Nahelem的相对吞吐量为1,而Sandy Bridge的相对吞吐量为0.5。
然而,即使MOVDQA
和MOVDQU
具有相同的延迟和每个处理器的倒数吞吐量,因为Nahelem并不意味着它们将提供相同的性能。如果地址不是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一起用于英特尔)。虽然在实践中,除了某些特殊情况外,不折叠可能没什么区别。