use*_*451 7 c++ sse intrinsics
我最初的尝试看起来像这样(假设我们想要成倍增加)
__m128 mat[n]; /* rows */
__m128 vec[n] = {1,1,1,1};
float outvector[n];
for (int row=0;row<n;row++) {
for(int k =3; k < 8; k = k+ 4)
{
__m128 mrow = mat[k];
__m128 v = vec[row];
__m128 sum = _mm_mul_ps(mrow,v);
sum= _mm_hadd_ps(sum,sum); /* adds adjacent-two floats */
}
_mm_store_ss(&outvector[row],_mm_hadd_ps(sum,sum));
}
Run Code Online (Sandbox Code Playgroud)
但这显然不起作用.我该如何处理?
我应该一次加载4个....
另一个问题是:如果我的数组很大(比如说n = 1000),我怎么能让它16字节对齐?这甚至可能吗?
好的...我将使用行主矩阵约定。每行[m]需要 (2) 个 __m128 元素来产生 8 个浮点数。8x1 向量v是列向量。由于您正在使用该haddps指令,我假设 SSE3 可用。发现r = [m] * v:
void mul (__m128 r[2], const __m128 m[8][2], const __m128 v[2])
{
__m128 t0, t1, t2, t3, r0, r1, r2, r3;
t0 = _mm_mul_ps(m[0][0], v[0]);
t1 = _mm_mul_ps(m[1][0], v[0]);
t2 = _mm_mul_ps(m[2][0], v[0]);
t3 = _mm_mul_ps(m[3][0], v[0]);
t0 = _mm_hadd_ps(t0, t1);
t2 = _mm_hadd_ps(t2, t3);
r0 = _mm_hadd_ps(t0, t2);
t0 = _mm_mul_ps(m[0][1], v[1]);
t1 = _mm_mul_ps(m[1][1], v[1]);
t2 = _mm_mul_ps(m[2][1], v[1]);
t3 = _mm_mul_ps(m[3][1], v[1]);
t0 = _mm_hadd_ps(t0, t1);
t2 = _mm_hadd_ps(t2, t3);
r1 = _mm_hadd_ps(t0, t2);
t0 = _mm_mul_ps(m[4][0], v[0]);
t1 = _mm_mul_ps(m[5][0], v[0]);
t2 = _mm_mul_ps(m[6][0], v[0]);
t3 = _mm_mul_ps(m[7][0], v[0]);
t0 = _mm_hadd_ps(t0, t1);
t2 = _mm_hadd_ps(t2, t3);
r2 = _mm_hadd_ps(t0, t2);
t0 = _mm_mul_ps(m[4][1], v[1]);
t1 = _mm_mul_ps(m[5][1], v[1]);
t2 = _mm_mul_ps(m[6][1], v[1]);
t3 = _mm_mul_ps(m[7][1], v[1]);
t0 = _mm_hadd_ps(t0, t1);
t2 = _mm_hadd_ps(t2, t3);
r3 = _mm_hadd_ps(t0, t2);
r[0] = _mm_add_ps(r0, r1);
r[1] = _mm_add_ps(r2, r3);
}
Run Code Online (Sandbox Code Playgroud)
至于对齐,__m128类型的变量应该在堆栈上自动对齐。对于动态内存,这不是一个安全的假设。一些 malloc/new 实现可能只返回保证 8 字节对齐的内存。
内在函数标头提供 _mm_malloc 和 _mm_free。在这种情况下,对齐参数应为 (16)。
| 归档时间: |
|
| 查看次数: |
866 次 |
| 最近记录: |