【发布时间】:2014-07-24 19:01:56
【问题描述】:
我想知道 SSE2 如何加快矩阵乘法
这是我的代码
int mat_mult_simd(double *a, double *b, double *c, int n)
{
__m128d c1,c2,a1,a2,b1;
for(int i=0; i<n/2; i++){
for(int j=0; j<n/2; j++){
c1 = _mm_load_pd(c+(2*j*n)+(i+2));
c2 = _mm_load_pd(c+n+(2*j*n)+(i+2));
for(int k=0; k<n; k++){
a1 = _mm_load1_pd(a+k+(2*j*n));
a2 = _mm load1_pd(a+n+k+(2*j*n));
b1 = _mm_load_pd(b+(k*n)+(i*2));
c1 = _mm_add_pd(c1, _mm_mul_pd(a1,b1));
c2 = _mm_add_pd(c2, _mm_mul_pd(a2,b1));
}
__mm_store_pd(c+(2*j*n)+(i+2), c1);
__mm_store_pd(c+n+(2*j*n)+(i+2), c2);
}
}
return 0;
}
每个参数的含义
'a' = 向量 a(MAT_SIZE*MAT_SIZE)
'b' = 向量 b(MAT_SIZE*MAT_SIZE)
'c' = 向量 c(MAT_SIZE*MAT_SIZE)
'n' = MAT_SIZE 是常数(它总是偶数且 >=2)
这段代码加速了大约 X4。反对
int mat_mult_default(double *a, double *b, double *c, int n)
{
double t;
for(int i=0; i<n; i++){
for(int j=0; j<n; j++){
t=0.0;
for(int k=0; k<n; k++)
t += a[i*n+k] * b[k*n+j];
c[i*n+j] = t;
}
}
}
但我想加快速度。我通常试验 MAT_SIZE 1000*1000 或 2000*2000。 我怎样才能加快速度?还有其他方法可以索引吗?我真的很想知道。谢谢。
【问题讨论】:
-
-1 只要求更好的性能而不给出任何理由是不现实的。说代码比某些东西快 4 倍而不指定它是什么也是不合理的。你需要做更多的努力来提出一个准确而具体的问题。您需要提供完整的基准测试程序,以明确您的数据来自何处。您需要提供典型的矩阵大小、样本数据等。
-
-1 为什么要自己编写这样的基本例程?使用英特尔 MKL 之类的库。如果是为了你学习SSE,请加这个。
-
@user2799037 写低级代码有什么问题?例如,每个像样的视频编码器/解码器都使用自己的 SIMD 程序集
-
@z̫͋ 低级代码只有在您知道自己在做什么时才有用。如果已经有高度优化的例程可用,为什么不使用它们呢?
-
您似乎是 SO 新手。让我给你一些建议。搜索 SSE 标签并单击投票以按最高投票排序。通读任务和答案。例如,您可以通过添加矩阵乘法来缩小搜索范围。这样做可以学到很多东西(比从许多书籍中学到的更多),并且可能会回答您自己的问题。
标签: c matrix simd intrinsics sse2