我是学习x86和ARM架构的学生.
我想知道将多个数据放入SIMD寄存器需要多少个周期?
据我所知,x86 SSE的xmms寄存器具有128位大小的寄存器.
如果我想通过SIMD指令集和汇编语言将32位8位数据从堆栈中放入xmms寄存器中,
对于通用寄存器的PUSH/POP,它具有相同的循环时间吗?
或者每8位数据需要32倍的时间吗?
感谢您的关注和关注!
简短回答:
如果您正在进行多次重复的128位负载,则可以使用Sandy Bridge,Ivy Bridge和Haswell在每个时钟周期实现两个128位负载,或者使用Nahelem在每个时钟周期进行一次128位负载.Nahelem之前的处理器取决于您是否进行了对齐加载或未对齐加载.
答案很长:
神秘主义者在Agner Fog的指令表中为您提供了所需的信息.但是让我为你(和我自己)拼出来.
您要查看的指令是: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 编写的代码使用qmake成功编译SSE指令(但SSE2无法识别),我得到了大约4%的下降.我认为这是由于地址穿过高速缓存行的情况(例如,一个高速缓存行中的前64位和另一个高速缓存中的下一个64位),否则性能相同.这实际上意味着MOVDQA
自Nahelem以来没有理由再使用了.唯一的区别在于内存对齐.
编辑:我说Haswell可以同时执行两个128位加载.实际上,它可以同时执行两个256负载.
编辑:事实证明,使用SSE未对齐的加载指令不能与另一个操作折叠.折叠允许CPU使用微操作融合(虽然它并不意味着它会融合但没有折叠它肯定不会融合). 因此,从Nehalem开始,说对齐加载指令已经过时并不完全准确.更准确地说它们已经过时了AVX(与Sandy Bridge一起用于英特尔).虽然,在实践中,除了某些特殊情况外,不折叠可能没什么区别.