c++ - 带返回条件的openmp优化
问题描述
我是 OpenMP 并行编程的新手,发现很难优化我的函数,如果一列为空,它应该返回 -1。
这是我的功能。源矩阵有一些值,并被norm_matrix
构造为对角矩阵,其中每一列保存源矩阵对应列的最大值。
我在 1000 的矩阵大小上执行此操作例如,如果我的源矩阵是
3 2 3 3
2 4 5 5
1 4 91 8
32 12 9 63
那么计算norm_matrix
将是
32 0 0 0
0 12 0 0
0 0 91 0
0 0 0 63
如果任何列包含全零,则该函数应返回 -1。
这是我试图在 OpenMP 中优化的功能:
int statistic_norm_matrix(double* source_matrix, double* norm_matrix, int size) {
int col, row;
for (col = 0; col < size; col++) {
norm_matrix[col * size + col] = source_matrix[col];
for (row = 0; row < size; row++) {
norm_matrix[col * size + col] = fmax(norm_matrix[col * size + col], source_matrix[row * size + col]);
}
if (norm_matrix[col * size + col] == 0) {
printf("can't process a matrix where the max col value is 0");
return -1;
}
norm_matrix[col * size + col] = (1 / norm_matrix[col * size + col]);
if (col == size - 1) {
print_matrix("matrix-norm", norm_matrix, size);
}
}
return 0;
这是与 OpenMP 并行化的尝试,但我没有发现性能差异:
int statistic_norm_matrix(double* source_matrix, double* norm_matrix, int size) {
int col, row;
int flag=0;
#pragma omp parallel for shared(source_matrix,norm_matrix) private(col,row)
for (col = 0; col < size; col++) {
norm_matrix[col * size + col] = source_matrix[col];
for (row = 0; row < size; row++) {
norm_matrix[col * size + col] = fmax(norm_matrix[col * size + col], source_matrix[row * size + col]);
}
if (norm_matrix[col * size + col] == 0) {
printf("can't process a matrix where the max col value is 0");
flag=-1;
}
norm_matrix[col * size + col] = (1 / norm_matrix[col * size + col]);
}
print_matrix("matrix-norm", norm_matrix, size);
return flag;
}
解决方案
当norm_matrix[col * size + col] == 0
您在语句上得到除以零错误时(1 / norm_matrix[col * size + col]);
。假设当flag = -1
您应该完全退出并行区域时,您应该使用 #pragma omp cancel for
int statistic_norm_matrix(double* source_matrix, double* norm_matrix, int size) {
int flag = 0;
#pragma omp parallel for shared(source_matrix,norm_matrix)
for (int col = 0; col < size; col++) {
norm_matrix[col * size + col] = source_matrix[col];
for (int row = 0; row < size; row++) {
norm_matrix[col * size + col] = fmax(norm_matrix[col * size + col], source_matrix[row * size + col]);
}
if (norm_matrix[col * size + col] == 0) {
flag = -1;
#pragma omp cancel for
}
norm_matrix[col * size + col] = (1 / norm_matrix[col * size + col]);
}
print_matrix("matrix-norm", norm_matrix, size);
return flag;
}
我在我的机器(即,有 4 个内核)上做了一个快速基准测试,测量了statistic_norm_matrix
单独的时间,不计算print_matrix
, 和矩阵1000x1000
:
1 线程:所用时间为 0.010852 (s)
2 线程时间为 0.005325 (s)
4 线程时间为 0.002891 (s)
对于矩阵10000x10000
:
1 线程时间为 1.937415 (s)
2 线程时间为 1.052908 (s)
4 线程时间为 0.807185 (s)
1 个线程的测试是在没有任何openmp
指令的情况下完成的。所以要么编译/运行的方式有问题,你的代码实际上没有并行运行,要么你测量时间的方式有问题。
推荐阅读
- svg - 跨平台安全使用的 SVG 字体
- python - 列表中是否使用了自引用列表或循环引用,例如。将列表附加到自身
- python - 模拟调用另一个方法的方法
- reactjs - react-native-router-flux Actions.{key} 无法识别并在调用时导致错误
- rest - 从客户端的角度看幂等键
- c# - Specflow - 场景大纲测试被忽略
- python - 使用来自另一列的滚动值的数据框百分位数
- javascript - 接受来自 javascript 的 Jquery.post 和 Python 的 request.post 的 json
- javascript - React JSX 错误期望在箭头函数的末尾有一个返回值
- javascript - 在 Cytoscape.js 中设置节点位置