gpt4 book ai didi

c++ - C++ OpenMP 中线性代数函数的高效并行化

转载 作者:太空宇宙 更新时间:2023-11-04 12:57:06 25 4
gpt4 key购买 nike

我在并行编程方面经验很少,想知道是否有人可以快速浏览一下我编写的代码,看看是否有任何明显的方法可以提高计算效率。

困难的产生是因为我有多个维度不等的矩阵运算需要计算,所以我不确定最简洁的计算编码方式。

下面是我的代码。请注意此代码确实有效。我正在使用的矩阵的尺寸约为 700x700 [参见下面的 int s] 或 700x30 [int n]。

此外,我正在为我的顺序代码使用 armadillo 库。使用 openMP 进行并行化但保留 Armadillo 矩阵类的情况可能比默认使用标准库要慢;有没有人对此有意见(在我花几个小时大修之前!)?

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 倍。

对于这种大小的矩阵,“可变维度”问题所涉及的开销可能超过并行化的好处。任何见解将不胜感激。

提前致谢

jack

最佳答案

如果您使用的编译器可以纠正错误的循环嵌套并融合循环以改善非并行构建的内存局部性,则 openmp 可能会禁用这些优化。正如其他人所推荐的,您应该考虑使用优化的库,例如 mkl 或 acml。通常随发行版提供的默认 gfortran blas 不是多线程的。

关于c++ - C++ OpenMP 中线性代数函数的高效并行化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46077992/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com