_mm_broadcast_ss比_mm_set1_ps快吗?

时间:2012-11-04 12:09:29

标签: vectorization avx

这是代码吗

float a = ...;
__m256 b = _mm_broadcast_ss(&a)

总是比这段代码快

float a = ...;
_mm_set1_ps(a)

如果a定义为static const float a = ...而非float a = ...

,该怎么办?

3 个答案:

答案 0 :(得分:8)

如果您定位AVX指令集,gcc将使用VBROADCASTSS来实现_mm_set1_ps内在函数。但是,Clang将使用两条指令(VMOVSS + VPSHUFD)。

答案 1 :(得分:8)

_mm_broadcast_ss具有架构强加的弱点,这些弱点主要由 mm SSE API隐藏。最重要的区别如下:

  • _mm_broadcast_ss仅限于从内存加载值。

这意味着如果在源不在内存中的情况下显式使用_mm_broadcast_ss,那么结果的效率可能低于使用_mm_set1_ps的效率。当加载立即值(常量)或使用最近计算的结果时,通常会发生这种情况。在这些情况下,结果将由编译器映射到寄存器。要使用广播值,编译器必须将值转储回内存。或者,可以使用pshufd直接从寄存器中进行splat。

_mm_set1_ps是实现定义的,而不是映射到特定的底层cpu操作(指令)。这意味着它可能会使用几个SSE指令之一来执行splat。启用了AVX支持的智能编译器应该在适当的时候内部使用vbroadcastss,但它取决于编译器优化器的AVX实现状态。

如果您非常有信心从内存加载 - 例如迭代数据 - 那么直接使用广播就可以了。但如果有任何疑问,我建议坚持使用_mm_set1_ps。

static const float的特定情况下,您绝对要避免使用_mm_broadcast_ss()。

答案 2 :(得分:5)

mm_broadcast_ss可能比mm_set1_ps更快。前者转换为单个指令(VBROADCASTSS),而后者则使用多个指令(可能是MOVSS后跟shuffle)进行仿真。但是,mm_broadcast_ss需要AVX指令集,而mm_set1_ps只需要SSE。