我正在尝试测试一小段代码的速度,如下所示:
for(i=0;i<imgDim;i++)
{
X[0][i] = Z[i] - U1[i] * rhoinv;
X[1][i] = Z[i] - U2[i] * rhoinv;
X[2][i] = Z[i] - U3[i] * rhoinv;
}
迭代次数约为200次,imgDim为1000000。这段代码的总时间约为2秒。整个代码花费了大约15秒。 但是当我使用 openmp 并行这段代码后,如下所示:
omp_set_num_threads(max_threads);
#pragma omp parallel shared(X,Z,U1,U2,U3,imgDim,rhoinv) private(i)
{
#pragma omp for schedule(dynamic)
for(i=0;i<imgDim;i++)
{
X[0][i] = Z[i] - U1[i] * rhoinv;
X[1][i] = Z[i] - U2[i] * rhoinv;
X[2][i] = Z[i] - U3[i] * rhoinv;
}
}
max_threads 为 8。仅这一小段代码就需要大约 11 秒,整个代码大约需要 27 秒。最奇怪的是,如果我将 max_threads 更改为 1,时间会减少到 6 秒。但仍然比顺序代码长得多。
花了我很多时间也找不到问题所在。如果有人能帮助我,我将深表谢意。
最佳答案
schedule(dynamic)
引入了巨大的运行时开销。它应该仅用于每次迭代可能花费不同时间的循环,并且改进的负载平衡将证明开销是合理的。对于像您这样的常规循环,动态调度是一种过度杀伤力,因为它引入了不必要的开销,从而减慢了计算速度。
将计划类型更改为静态
:
#pragma omp parallel for schedule(static)
for(i=0;i<imgDim;i++)
{
X[0][i] = Z[i] - U1[i] * rhoinv;
X[1][i] = Z[i] - U2[i] * rhoinv;
X[2][i] = Z[i] - U3[i] * rhoinv;
}
(注意:外部作用域中声明的变量默认是共享的,并行循环控制变量是隐式私有(private)的)
关于parallel-processing - 使用 openmp 速度明显减慢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14743630/