我如何使用SSE执行8 × 8矩阵操作
How do I perform 8 x 8 matrix operation using SSE?
我最初的尝试是这样的(假设我们想要相乘)
__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));
}
但这显然不起作用。我该怎么做呢?
我应该一次加载4个....
另一个问题是:如果我的数组非常大(比如n = 1000),我怎么能使它16字节对齐?这可能吗?
OK…我将使用行矩阵约定。[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);
}
至于对齐,__m128类型的变量应该在堆栈上自动对齐。对于动态内存,这不是一个安全的假设。一些malloc/new实现可能只返回保证为8字节对齐的内存。
intrinsics头文件提供了_mm_malloc和_mm_free。在本例中,align参数应为(16)。
Intel开发了一个小矩阵库,用于大小范围从1×1到6×6的矩阵。应用说明AP-930流SIMD扩展-矩阵乘法详细描述了乘法两个6×6矩阵的算法。这应该可以适应其他大小的矩阵。
相关文章:
- 对字符数组中的元素执行逐位操作
- 排序时无法执行交换操作.我做的时候它会崩溃.为什么
- C++ 随机数生成器:尝试将结果作为向量获取,但通过制作 void 函数来执行此操作而出现错误
- 对OpenMP reduction子句中的变量执行原子操作
- 无法调用成员函数,尝试正确执行此操作仍然失败
- 不执行任何操作的函数调用C++
- 如何通过使用 2 位或更多数字的 XOR 运算符来执行此操作C++问题
- 这将执行默认移动操作吗?
- 当我告诉它通过控制台执行此操作时,我的c ++循环不会停止
- 如果普通默认构造函数不执行任何操作,为什么我们不能使用 malloc 创建平凡可构造的对象?
- 生成线程并在运行时执行其他操作,只要它处于活动状态
- 如何检测函数是否执行IO操作
- GDI+-无法对Gdiplus::Graphics(C++)执行任何操作
- 可执行文件库加载的操作
- 如何防止GUI挂起,同时允许第二次操作与Qt中的第一次操作一起执行
- 按下Arduino按钮后,如何在C#应用程序上执行操作
- 如何在没有外部库的情况下使用C++03约束执行基于正则表达式的字符串操作
- 在 "CodePad" 中执行链表操作时转储的核心(这是一个在线C++编译器)
- 是否可以访问类数据成员并在析构函数中对它们执行操作?
- 每个操作执行两次