c – 如何使用SSE执行8 x 8矩阵运算?

前端之家收集整理的这篇文章主要介绍了c – 如何使用SSE执行8 x 8矩阵运算?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我最初的尝试看起来像这样(假设我们想要成倍增加)
  1. __m128 mat[n]; /* rows */
  2. __m128 vec[n] = {1,1,1};
  3. float outvector[n];
  4. for (int row=0;row<n;row++) {
  5. for(int k =3; k < 8; k = k+ 4)
  6. {
  7. __m128 mrow = mat[k];
  8. __m128 v = vec[row];
  9. __m128 sum = _mm_mul_ps(mrow,v);
  10. sum= _mm_hadd_ps(sum,sum); /* adds adjacent-two floats */
  11. }
  12. _mm_store_ss(&outvector[row],_mm_hadd_ps(sum,sum));
  13. }

但这显然不起作用.我该如何处理?

我应该一次加载4个….

另一个问题是:如果我的数组非常大(比如n = 1000),我该如何才能使它16字节对齐?这有可能吗?

解决方法

好的……我将使用行主矩阵约定. [m]的每一行需要(2)__m128元素才能产生8个浮点数. 8×1向量v是列向量.由于您正在使用haddps指令,我将假设SSE3可用.求r = [m] * v:
  1. void mul (__m128 r[2],const __m128 m[8][2],const __m128 v[2])
  2. {
  3. __m128 t0,t1,t2,t3,r0,r1,r2,r3;
  4.  
  5. t0 = _mm_mul_ps(m[0][0],v[0]);
  6. t1 = _mm_mul_ps(m[1][0],v[0]);
  7. t2 = _mm_mul_ps(m[2][0],v[0]);
  8. t3 = _mm_mul_ps(m[3][0],v[0]);
  9.  
  10. t0 = _mm_hadd_ps(t0,t1);
  11. t2 = _mm_hadd_ps(t2,t3);
  12. r0 = _mm_hadd_ps(t0,t2);
  13.  
  14. t0 = _mm_mul_ps(m[0][1],v[1]);
  15. t1 = _mm_mul_ps(m[1][1],v[1]);
  16. t2 = _mm_mul_ps(m[2][1],v[1]);
  17. t3 = _mm_mul_ps(m[3][1],v[1]);
  18.  
  19. t0 = _mm_hadd_ps(t0,t3);
  20. r1 = _mm_hadd_ps(t0,t2);
  21.  
  22. t0 = _mm_mul_ps(m[4][0],v[0]);
  23. t1 = _mm_mul_ps(m[5][0],v[0]);
  24. t2 = _mm_mul_ps(m[6][0],v[0]);
  25. t3 = _mm_mul_ps(m[7][0],t3);
  26. r2 = _mm_hadd_ps(t0,t2);
  27.  
  28. t0 = _mm_mul_ps(m[4][1],v[1]);
  29. t1 = _mm_mul_ps(m[5][1],v[1]);
  30. t2 = _mm_mul_ps(m[6][1],v[1]);
  31. t3 = _mm_mul_ps(m[7][1],t3);
  32. r3 = _mm_hadd_ps(t0,t2);
  33.  
  34. r[0] = _mm_add_ps(r0,r1);
  35. r[1] = _mm_add_ps(r2,r3);
  36. }

至于对齐,__ m128类型的变量应该在堆栈上自动对齐.对于动态内存,这不是一个安全的假设.一些malloc / new实现可能只返回保证为8字节对齐的内存.

intrinsics标头提供_mm_malloc和_mm_free.在这种情况下,align参数应为(16).

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