我对 C 相当陌生,对于我的大部分研究来说,不需要比 python 更快的东西。然而,事实证明我最近所做的工作需要计算相当大的向量/矩阵,因此 C+MPI 解决方案可能是合适的。
从数学上来说,任务非常简单。我有很多维数约为 40k 的向量并希望计算克罗内克产品选定的这些向量对,然后对这些克罗内克乘积求和。
问题是,如何有效地做到这一点?下面的代码结构,使用for循环,或者得到的效果有什么问题吗?
功能kron
下面描述的传递向量A
and B
长度vector_size
,并计算其克罗内克积,并将其存储在C
, a vector_size*vector_size
matrix.
void kron(int *A, int *B, int *C, int vector_size) {
int i,j;
for(i = 0; i < vector_size; i++) {
for (j = 0; j < vector_size; j++) {
C[i*vector_size+j] = A[i] * B[j];
}
}
return;
}
这对我来说似乎很好,并且当然(如果我没有犯一些愚蠢的语法错误)会产生正确的结果,但我偷偷怀疑嵌入的 for 循环不是最佳的。如果我应该采取其他方法来解决这个问题,请告诉我。欢迎提出建议。
我感谢您的耐心以及您可能提出的任何建议。再说一次,我对 C 非常缺乏经验,但是谷歌搜索并没有给我带来这个查询的乐趣。
由于您的循环体都是完全独立的,因此肯定有一种方法可以加速这一过程。最简单的方法是在考虑 MPI 之前就已经利用多个内核。 OpenMP 在这方面应该做得很好。
#pragma omp parallel for
for(int i = 0; i < vector_size; i++) {
for (int j = 0; j < vector_size; j++) {
C[i][j] = A[i] * B[j];
}
}
如今许多编译器都支持这一点。
您还可以尝试将一些常见表达式拖出内部循环,但像 gcc、icc 或 clang 等不错的编译器应该可以很好地自行完成此操作:
#pragma omp parallel for
for(int i = 0; i < vector_size; ++i) {
int const x = A[i];
int * vec = &C[i][0];
for (int j = 0; j < vector_size; ++j) {
vec[j] = x * B[j];
}
}
顺便说一句,索引int
通常这不是正确的做法。size_t
是正确的typedef
对于与对象的索引和大小有关的所有内容。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)