【发布时间】:2017-09-06 14:33:59
【问题描述】:
我几乎没有并行编程经验,想知道是否有人可以快速浏览一下我编写的一些代码,看看是否有任何明显的方法可以提高计算效率。
之所以出现困难,是因为我需要计算多个维度不等的矩阵运算,因此我不确定最简洁的计算编码方式。
下面是我的代码。请注意,此代码确实有效。我正在使用的矩阵的尺寸约为 700x700 [参见下面的 int s] 或 700x30 [int n]。
另外,我将犰狳库用于我的顺序代码。使用 openMP 进行并行化但保留犰狳矩阵类可能比默认使用标准库慢;有没有人对此有意见(在我花几个小时大修之前!)?
double start, end, dif;
int i,j,k; // iteration counters
int s,n; // matrix dimensions
mat B; B.load(...location of stored s*n matrix...) // input objects loaded from file
mat I; I.load(...s*s matrix...);
mat R; R.load(...s*n matrix...);
mat D; D.load(...n*n matrix...);
double e = 0.1; // scalar parameter
s = B.n_rows; n = B.n_cols;
mat dBdt; dBdt.zeros(s,n); // object for storing output of function
// 100X sequential computation using Armadillo linear algebraic functionality
start = omp_get_wtime();
for (int r=0; r<100; r++) {
dBdt = B % (R - (I * B)) + (B * D) - (B * e);
}
end = omp_get_wtime();
dif = end - strt;
cout << "Seq computation: " << dBdt(0,0) << endl;
printf("relaxation time = %f", dif);
cout << endl;
// 100 * parallel computation using OpenMP
omp_set_num_threads(8);
for (int r=0; r<100; r++) {
// parallel computation of I * B
#pragma omp parallel for default(none) shared(dBdt, B, I, R, D, e, s, n) private(i, j, k) schedule(static)
for (i = 0; i < s; i++) {
for (j = 0; j < n; j++) {
for (k = 0; k < s; k++) {
dBdt(i, j) += I(i, k) * B(k, j);
}
}
}
// parallel computation of B % (R - (I * B))
#pragma omp parallel for default(none) shared(dBdt, B, I, R, D, e, s, n) private(i, j) schedule(static)
for (i = 0; i < s; i++) {
for (j = 0; j < n; j++) {
dBdt(i, j) = R(i, j) - dBdt(i, j);
dBdt(i, j) *= B(i, j);
dBdt(i, j) -= B(i, j) * e;
}
}
// parallel computation of B * D
#pragma omp parallel for default(none) shared(dBdt, B, I, R, D, e, s, n) private(i, j, k) schedule(static)
for (i = 0; i < s; i++) {
for (j = 0; j < n; j++) {
for (k = 0; k < n; k++) {
dBdt(i, j) += B(i, k) * D(k, j);
}
}
}
}
end = omp_get_wtime();
dif = end - strt;
cout << "OMP computation: " << dBdt(0,0) << endl;
printf("relaxation time = %f", dif);
cout << endl;
如果我超线程 4 个核心,我会得到以下输出:
Seq computation: 5.54926e-10
relaxation time = 0.130031
OMP computation: 5.54926e-10
relaxation time = 2.611040
这表明虽然两种方法产生相同的结果,但并行公式比顺序公式慢大约 20 倍。
对于这种大小的矩阵,这个“可变维度”问题所涉及的开销可能超过并行化的好处。任何见解将不胜感激。
提前致谢,
杰克
【问题讨论】:
-
我不清楚你到底想做什么?所以犰狳代码有效并且做了它应该做的事情?然后使用它。如果您正确设置犰狳,它会尽可能快(缓存、simd、多线程;在内部使用BLAS),可能只是缺少矩阵重新排序(不确定是否已完成或支持)。
-
在每个并行循环之后都有一个栅栏,即所有线程都等到最后一个循环结束。您有 3 个单独的并行部分,它们闻起来像是执行时间中一个很大的有效非并行部分。另外 700x700 不是一个很大的矩阵,也许你需要增加尺寸才能看到并行运行的好处
-
我希望通过在具有 4 个以上内核的 HPC 上运行模拟来提高计算速度。内部 BLAS 实现是否自动使用所有可用内核?
-
@jack.l 恕我直言,应该清楚,过程中不存在任何矩阵链。
BD和IB都不是矩阵链。最好专注于核心问题。 -
@user3666197 好的。那是我的事,因为我没有仔细评估他的代码并提到了两次。
标签: c++ matrix parallel-processing openmp armadillo