使用 OpenMP 的并行代码比串行代码需要更多的时间来执行
Parallel code with OpenMP takes more time to execute than serial code
我正在尝试将此代码并行化为 运行。这是一个大项目的代码块。我想我开始慢慢并行化,看看是否有问题(我不知道这是不是一个好策略,所以请告诉我)。
double best_nearby(double delta[MAXVARS], double point[MAXVARS], double prevbest, int nvars)
{
double z[MAXVARS];
double minf, ftmp;
int i;
minf = prevbest;
omp_set_num_threads(NUM_THREADS);
#pragma omp parallel for shared(nvars,point,z) private(i)
for (i = 0; i < nvars; i++)
z[i] = point[i];
for (i = 0; i < nvars; i++) {
z[i] = point[i] + delta[i];
ftmp = f(z, nvars);
if (ftmp < minf)
minf = ftmp;
else {
delta[i] = 0.0 - delta[i];
z[i] = point[i] + delta[i];
ftmp = f(z, nvars);
if (ftmp < minf)
minf = ftmp;
else
z[i] = point[i];
}
}
for (i = 0; i < nvars; i++)
point[i] = z[i];
return (minf);
}
NUM_THREADS 是#defined
函数多了一些行,但是并行和串行是一样的
看起来串行代码平均需要 130 秒,因此并行代码大约需要 400 秒。令我困惑的是,这么小的变化会导致 exe 时间增加这么多。关于为什么会发生这种情况的任何想法?提前致谢!
double f(double *x, int n){
double fv;
int i;
funevals++;
fv = 0.0;
for (i=0; i<n-1; i++) /* rosenbrock */
fv = fv + 100.0*pow((x[i+1]-x[i]*x[i]),2) + pow((x[i]-1.0),2);
return fv;
}
目前,您的并行化程度不高。您可以从并行化 f
函数开始,因为它看起来对计算要求很高:
double f(double *x, int n){
..
double fv = 0.0;
#pragma omp parallel for reduction(+:fv)
for (int i=0; i<n-1; i++)
fv = fv + 100.0*pow((x[i+1]-x[i]*x[i]),2) + pow((x[i]-1.0),2);
return fv;
}
测试并检查结果。之后,您可以尝试扩大并行化的范围,以包括最外层的循环。
我正在尝试将此代码并行化为 运行。这是一个大项目的代码块。我想我开始慢慢并行化,看看是否有问题(我不知道这是不是一个好策略,所以请告诉我)。
double best_nearby(double delta[MAXVARS], double point[MAXVARS], double prevbest, int nvars)
{
double z[MAXVARS];
double minf, ftmp;
int i;
minf = prevbest;
omp_set_num_threads(NUM_THREADS);
#pragma omp parallel for shared(nvars,point,z) private(i)
for (i = 0; i < nvars; i++)
z[i] = point[i];
for (i = 0; i < nvars; i++) {
z[i] = point[i] + delta[i];
ftmp = f(z, nvars);
if (ftmp < minf)
minf = ftmp;
else {
delta[i] = 0.0 - delta[i];
z[i] = point[i] + delta[i];
ftmp = f(z, nvars);
if (ftmp < minf)
minf = ftmp;
else
z[i] = point[i];
}
}
for (i = 0; i < nvars; i++)
point[i] = z[i];
return (minf);
}
NUM_THREADS 是#defined
函数多了一些行,但是并行和串行是一样的
看起来串行代码平均需要 130 秒,因此并行代码大约需要 400 秒。令我困惑的是,这么小的变化会导致 exe 时间增加这么多。关于为什么会发生这种情况的任何想法?提前致谢!
double f(double *x, int n){
double fv;
int i;
funevals++;
fv = 0.0;
for (i=0; i<n-1; i++) /* rosenbrock */
fv = fv + 100.0*pow((x[i+1]-x[i]*x[i]),2) + pow((x[i]-1.0),2);
return fv;
}
目前,您的并行化程度不高。您可以从并行化 f
函数开始,因为它看起来对计算要求很高:
double f(double *x, int n){
..
double fv = 0.0;
#pragma omp parallel for reduction(+:fv)
for (int i=0; i<n-1; i++)
fv = fv + 100.0*pow((x[i+1]-x[i]*x[i]),2) + pow((x[i]-1.0),2);
return fv;
}
测试并检查结果。之后,您可以尝试扩大并行化的范围,以包括最外层的循环。