我正在启动一个通过 OpenMP 并行化的给定问题。它对处理大量数据的同一段代码运行给定次数的迭代。处于应用 OpenMP 的那个级别,使每个线程处理一个子卷。每个迭代都应该具有相同的工作负载,以及每个子卷。
当使用 ICC 编译时,迭代的持续时间总是与预期的相同。但奇怪的是:当使用 GCC 编译时,每次迭代的时间开始增加,达到最大值,然后再次减少,直到达到稳定的给定值。没有 OpenMP 编译的相同程序在使用 ICC 或 GCC 时没有区别。
有没有人在这些编译器中观察到 OpenMP 中的这种行为?
[编辑 1]:指导和静态调度策略已经过测试。
[编辑 2]:代码看起来有点像这样:
#pragma omp parallel for schedule(static) private(i,j,k)
for(i = 0; i < N; i++)
for(j = 0; j < N; j++)
for(k = 0; k < N; k++){
a[ k+j*N+i*NN] = 0.f;
b[ k+j*N+i*NN] = 0.f;
c[ k+j*N+i*NN] = 0.f;
d[ k+j*N+i*NN] = 0.f;
}
for( t = 0; t < T; t+=dt){
/* ... change some discrete values in a,b,c .... */
/* and propagate changes */
#pragma omp parallel for schedule(static) private(i,j,k)
for(i = 0; i < N; i++)
for(j = 0; j < N; j++)
for(k = 0; k < N; k++){
d[ k+j*N+i*NN ] = COMP( a,b,c,k+j*N+i*NN );
}
}
其中 COMP 在 k+j*N+i*NN (以及它们的一些邻居)位置对 a、b、c 中的值进行某种线性应用。关键是 GCC 和 ICC 中的这段代码导致了我描述的问题。关键是我发现我将 a,b,c,d 的初始化更改为 0.0f (f.ex, 0.5f) 以外的某个值,即不会发生每个时间步所花费的时间增加的事情。
[编辑 3]:似乎不是 GOMP 的错。禁用 OpenMP 时也会发生同样的情况。再一次,使用 ICC(没有或使用 openmp)根本不会发生。有什么办法可以关闭这个线程吗?