c – 对于具有所有相同组件的SSE向量,可以动态生成还是预先计算?

前端之家收集整理的这篇文章主要介绍了c – 对于具有所有相同组件的SSE向量,可以动态生成还是预先计算?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
当我需要执行一个向量操作,其操作数只是一个广播到每个组件的一个浮点数时,我应该预先计算__m256或__m128,并在需要时加载它,或者每次我使用_mm_set1_ps将浮点数广播到寄存器需要矢量?

我一直在预先计算非常重要和高度使用的向量,并在运行中生成那些不太重要的向量.但我真的通过预先计算获得了任何速度吗?这值得吗?

_mm_set1_ps是用单个指令实现的吗?这可能会回答我的问题.

解决方法

当然,它将依赖于您的代码,但我已经使用这两种方法实现了两个简单的函数. See code
__m128 calc_set1(float num1,float num2)
{
  __m128 num1_4 = _mm_set1_ps(num1);
  __m128 num2_4 = _mm_set1_ps(num2);
  __m128 result4 = _mm_mul_ps(num1_4,num2_4);

  return result4;
}

__m128 calc_mov(float* num1_4_addr,float* num2_4_addr)
{
   __m128 num1_4 = _mm_load_ps(num1_4_addr);
  __m128 num2_4 = _mm_load_ps(num2_4_addr);
  __m128 result4 = _mm_mul_ps(num1_4,num2_4);

  return result4;
}

和装配

calc_set1(float,float):
    shufps  $0,%xmm0,%xmm0
    shufps  $0,%xmm1,%xmm1
    mulps   %xmm1,%xmm0
    ret
calc_mov(float*,float*):
    movaps  (%rdi),%xmm0
    mulps   (%rsi),%xmm0
    ret

您可以看到calc_mov()按照您的预期执行,calc_set1()使用单个shuffle指令.

如果在高速缓存未命中的罕见事件中L1高速缓存的加载端口更忙,则movps指令可以花费大约四个周期来生成更多地址.

shufps将在最近的任何英特尔微体系结构上进行一个周期.无论是SSE128还是AVX256,我都相信这是真的.因此我建议使用mm_set1_ps方法.

当然,shuffle指令假定float已经在SSE / AVX寄存器中.如果您从内存加载它,那么广播将更好,因为它将在单个指令中捕获最好的movps和shufps.

猜你在找的C&C++相关文章