【问题标题】:assignment with intel Intrinsics - horizontal add使用 intel Intrinsics 分配 - 水平添加
【发布时间】:2018-10-22 19:16:43
【问题描述】:

我想总结一个大向量ary 的所有元素。我的想法是用水平总和来做。

const int simd_width = 16/sizeof(float); 
float helper[simd_width];

//take the first 4 elements
const __m128 a4 = _mm_load_ps(ary);

for(int i=0; i<N-simd_width; i+=simd_width){
     const __m128 b4 = _mm_load_ps(ary+i+simd_width);
     //save temporary result in helper array
     _mm_store_ps(helper, _mm_hadd_ps(a4,b4)); //C
     const __m128 a4 = _mm_load_ps(helper);

}

我寻找了一种方法,通过它我可以将结果向量直接分配给 quadfloat a4 直接像 _mm_store_ps(a4, _mm_hadd_ps(a4,b4)) 有这样的英特尔方法吗? (这是我第一次使用 SSE - 可能整个代码 sn-p 是错误的)

【问题讨论】:

  • 抱歉我的英语不好。我想知道是否有一个 intel 内在函数,我可以直接将新值 C = _mm_hadd_ps(a4,b4) 分配给 a4。或者我可以直接覆盖 a4 像a4 = _mm_hadd_ps(a4,b4)
  • 没有内在的,你可以用=分配它
  • 这样我就可以直接用a4 = _mm_hadd_ps(a4,b4);重用a4了
  • 是的。水平添加虽然很慢,所以最好少用多用_mm_add_ps
  • 看看 clang 或 ICC 如何自动矢量化循环,使用带有两个或更多累加器的垂直加法,然后在末尾进行水平总和。 Unroll loop and do independent sum with vectorization。这比使用haddps 对每个向量进行 2 次随机播放要快得多。见Fastest way to do horizontal float vector sum on x86

标签: c++ sse simd


【解决方案1】:

正如彼得建议的那样,不要使用水平总和。使用垂直总和。

例如,在伪代码中,simd width = 2

SIMD sum = {0,0}; // we use 2 accumulators
for (int i = 0; i + 1 < n; i += 2)
    sum = simd_add(sum, simd_load(x+i));
float s = horizzontal_add(sum);
if (n & 1)  // n was not a multiple of 2?
   s += x[n-1]; // deal with last element

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-09
    • 1970-01-01
    • 2021-10-23
    • 2010-10-05
    • 1970-01-01
    • 2013-02-28
    相关资源
    最近更新 更多