存在OpenMP循环并行化时缺少发布构建优化

时间:2013-09-26 17:36:26

标签: c++ performance optimization parallel-processing openmp

下面的C ++代码片段为循环提供了一个嵌套的,在内层执行3x3矩阵乘法。

int main()
{
    double sum = 0;
#pragma omp parallel for reduction(+: sum)
    for (int i=0;i<30;i++)
    {
        double eledir[3][3], noddir[3][3];

        for (int j=0;j<200000;++j)
        {
            eledir[0][0]=2*i+j; eledir[0][1]=2*i+j;
            eledir[0][2]=2*i+j; eledir[1][0]=4*i+j;
            eledir[1][1]=3*i+j; eledir[1][2]=4*i+j;
            eledir[2][0]=5*i+j; eledir[2][1]=6*i+j;
            eledir[2][2]=7*i+j;

            noddir[0][0]=2*i-2*j;   noddir[0][1]=1*i-2*j;
            noddir[0][2]=3*i-6*j;   noddir[1][0]=4*i-5*j;
            noddir[1][1]=5*i-2*j;   noddir[1][2]=4*i-4*j;
            noddir[2][0]=6*i-2*j;   noddir[2][1]=7*i-2*j;
            noddir[2][2]=8*i-3*j;

            //-- Matrix multiplication ----
            sum += mat_mul(eledir, noddir)/(sum+1);
        }
    }
    return (int) sum;
}

OpenMP用于使用版本构建设置并行化此常规循环,并未显示相对于核心数的线性加速。

特别是,考虑到代码片段中的内部循环在串行执行中大约需要4毫秒。当外部环路在6个内核之间进行分区时,每个内部环路大约需要30毫秒,取消了通过并行化实现的加速,并使其比串行代码更慢。

比较调试版本的时间,我学会了30毫秒是执行未优化的内部循环的时间。因此,出于某种原因,优化不会在openMP并行化的情况下发生。你知道为什么会发生这样的事情,以及如何避免它?

代码示例简化并从非平凡代码中重现。

double mat_mul(double a[3][3], double b[3][3])
{
    static double c[3][3];      

    c[0][0] = a[0][0]*b[0][0]+a[0][1]*b[1][0]+a[0][2]*b[2][0];
    c[0][1] = a[0][0]*b[0][1]+a[0][1]*b[1][1]+a[0][2]*b[2][1];
    c[0][2] = a[0][0]*b[0][2]+a[0][1]*b[1][2]+a[0][2]*b[2][2];

    c[1][0] = a[1][0]*b[0][0]+a[1][1]*b[1][0]+a[1][2]*b[2][0];
    c[1][1] = a[1][0]*b[0][1]+a[1][1]*b[1][1]+a[1][2]*b[2][1];
    c[1][2] = a[1][0]*b[0][2]+a[1][1]*b[1][2]+a[1][2]*b[2][2];

    c[2][0] = a[2][0]*b[0][0]+a[2][1]*b[1][0]+a[2][2]*b[2][0];
    c[2][1] = a[2][0]*b[0][1]+a[2][1]*b[1][1]+a[2][2]*b[2][1];
    c[2][2] = a[2][0]*b[0][2]+a[2][1]*b[1][2]+a[2][2]*b[2][2];

    return c[0][0]+c[0][1]+c[0][2]+c[1][0]+c[1][1]+c[1][2]+c[2][0]+c[2][1]+c[2][2];
}

发布版本中的优化标志:/ O2(最大化速度),/ Oi(启用内部函数),/ GL(整个程序优化),/ openmp以支持OpenMP,Visual C ++编译器,Windows 7。

更新:使用intel编译器(icc)时,这个问题不太明显。但是仍然不确定为什么在使用MSVC ++时会发生这种减速以及如何避免它。

UPDATE2:正如Mysticial指出的那样,问题是由mat_mul中的“static”关键字引起的。在使用OpenMP时,应谨慎对待静态变量。删除“static”关键字解决了这个问题。

0 个答案:

没有答案