使用OpenMP获得错误的结果

时间:2011-05-01 03:16:54

标签: c++ openmp

我编写了一个将矢量乘以矩阵的程序。矩阵周期性地重复了单元格,因此我在乘法之前使用临时变量对向量元素求和。相邻行的周期相同。我为每个线程创建一个单独的临时变量。 sizeof(InnerVector)== 400,我不想在每次渲染时为其分配内存(= 600次)。

代码看起来像这样:

tempsSize = omp_get_max_threads();
InnerVector temps = new InnerVector[tempsSize];

for(int k = 0; k < tempsSize; k++)
    InnerVector_init(temps[k]);

for(int jmin = 1, jmax = 2; jmax < matrixSize/2; jmin *= 2, jmax *= 2)
{
    int period = getPeriod(jmax);

    #pragma omp parallel
    {
        int threadNum = omp_get_thread_num();
        // printf("\n threadNum = %i", threadNum);

        #pragma omp for
        for(int j = jmin; j < jmax; j++)
        {
            InnerVector_reset(temps[threadNum]);   
            for(int i = jmin; i < jmax; i++)
            {
                InnerMatrix cell = getCell(i, j);
                if(temps[threadNum].IsZero)
                    for(int k = j; k < matrixSize; k += period)
                        InnerVector_add(temps[threadNum], temps[threadNum], v[k]);
                InnerVector_add_mul(v_res[i], cell, temps[threadNum]);
            }
        }
    }
}

代码看起来是正确的,但结果错了。事实上,我对不同的运行得到不同的结果......有时结果是正确的。

当我在调试模式下编译时,结果总是正确的。 当我用“printf”取消注释行时,结果总是正确的。

P.S。我使用Visual Studio 2010。

1 个答案:

答案 0 :(得分:3)

我怀疑可能会有数据竞争 InnerVector_add_mul(v_res[i], cell, temps[threadNum]);

由于v_res似乎是结果向量,并且i在并行化循环的每次迭代中从jmin更改为jmax,因此可能会发生多个线程写入至v_res[i]的{​​{1}}值相同,结果不可预测。