使用openmp大幅减速

时间:2013-02-07 04:35:26

标签: parallel-processing openmp

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

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

这花了我很多时间,我找不到问题。非常感谢有人能帮助我。

1 个答案:

答案 0 :(得分: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;
}

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