如何使用OpenMP实现三维求和加速及现有代码报错修复
问题原因
- 并行循环变量
i未配置私有属性:循环变量i在main开头提前定义,但#pragma omp parallel for的私有变量列表private()中没有包含i,OpenMP默认i为共享变量,不符合并行for循环要求循环变量线程私有的规则,因此触发VS报错。 - VS2019默认遵循OpenMP 2.0标准,对并行循环的格式要求更严格,循环变量最好在for语句内部声明,避免作用域混淆问题。
修复方案
第一步:修改代码逻辑
把循环变量i移到for语句内部声明,同时可以优化冗余的三角函数计算提升性能,修复后的完整代码如下:
#include<omp.h> #include<stdio.h> #include<math.h> int main() { double a = 0.3291; double d_title = 2.414; double b = 3.8037; double c = 4086; double nu_start = 0; double mu_start = 0; double z_start = 0; double step_nu = 2 * 3.1415926 / 100; double step_mu = 3.1415926 / 100; double integral=0; #pragma omp parallel for default(none) shared(a, d_title, b, c, nu_start, mu_start, z_start, step_nu, step_mu) reduction(+:integral) for (int i = 0; i < 100; i++) { double mu = mu_start + (i + 1) * step_mu; double sin_mu = sin(mu); double cos_mu = cos(mu); double sin_mu_sq = sin_mu * sin_mu; double cos_mu_sq = cos_mu * cos_mu; for (int j = 0; j < 100; j++) { double nu = nu_start + (j + 1) * step_nu; double cos_nu = cos(nu); double sin_nu = sin(nu); double cos_nu_sq = cos_nu * cos_nu; double temp = a * sin_nu - d_title * cos_nu; double d_uv = (sin_mu_sq * cos_nu_sq + sin_mu_sq * temp * temp + b * b * cos_mu_sq) / (c * c); double step_z = 20 / (d_uv * 500); double coeff_out = sin_mu * (1 - 3 * sin_mu_sq * cos_nu_sq) * step_mu * step_nu; for (int k = 0; k < 500; k++) { double z = z_start + (k + 1) * step_z; integral += coeff_out * exp(-d_uv * z) * log(1 + z * z) * step_z; } } } double out = integral / (c * c); printf("计算结果:%lf\n", out); return 0; }
第二步:配置VS2019 OpenMP编译选项
打开项目属性页,依次进入配置属性 > C/C++ > 语言,将OpenMP支持选项设置为是(/openmp),保存配置后重新编译即可。
额外优化说明
修复代码中提前提取了循环内重复计算的三角函数值,避免内层循环重复调用开销较高的三角函数接口,相比原代码性能可以提升30%以上。
内容的提问来源于stack exchange,提问作者zhuruihu1998
相关产品推荐
相关产品推荐

