2

我正在尝试测试一小段代码的速度,如下所示:

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 秒。但仍然比顺序代码长得多。

这花了我很多时间,我找不到问题。如果有人可以帮助我,我将不胜感激。

4

1 回答 1

3

schedule(dynamic)引入了巨大的运行时开销。它应该只用于每次迭代可能需要不同时间量的循环,并且改进的负载平衡将证明开销是合理的。对于像您这样的常规循环,动态调度是一种过度杀伤,因为它引入了不必要的开销,从而减慢了计算速度。

将计划类型更改为static

#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;
}

(注意:在外部范围内声明的变量默认是共享的,并行循环控制变量是隐式私有的)

于 2013-02-07T11:54:44.357 回答