【发布时间】:2021-12-05 00:10:30
【问题描述】:
我正在学习内在学。我不知道如何正确加载矩阵。我想做矩阵乘法。
这是我的代码:
int i, j, k;
__m128 mat2values = _mm_setzero_ps();
__m128 mat1values = _mm_setzero_ps();
__m128 r = _mm_setzero_ps();
for (i = 0; i < N; ++i)
{
for (j = 0; j < N - 3; j += 4)
{
for (k = 0; k < N - 3; k += 4)
{
mat1values = _mm_load_ps(&mat1[i][k]);
mat2values = _mm_load_ps(&mat2[k][j]);
r = _mm_add_ps(r, _mm_mul_ps(mat1values, mat2values));
}
result[i][j] = r.m128_f32[0] + r.m128_f32[1] + r.m128_f32[2] + r.m128_f32[3];
for (; k < N; k++)
result[i][j] += mat1[i][j] * mat2[k][j];
}
}
当调试结果在循环后仍将保持所有 0 值时。
【问题讨论】:
-
显示所有涉及的变量的声明。将其设为minimal reproducible example
-
IDK 为什么你会得到零,但请注意
_mm_load_ps(&mat2[k][j])加载_mm_load_ps(&mat2[k][j + 0..3]),因此如果一个矩阵尚未转置(即与连续列一起存储),那么对于简单的 matmul 来说这可能是错误的.您确定您的输入不为零,并且您的数据实际上是浮点数,而不是小的int值(其位模式将是次正常的浮点数,其乘积为零)?使用调试器在单步执行时查看变量值,如果您的负载真正加载零,请将其减少到 minimal reproducible example。 -
__m128 r = _mm_setzero_ps();应该在每行 x 列点积之前重新归零,而不仅仅是在顶部一次!在可能的最窄范围内声明您的__m128变量将首先避免该错误。但这并不能解释得到零。
标签: c matrix-multiplication sse intrinsics