并行化给出错误的输出

时间:2013-11-10 20:27:27

标签: c openmp

尝试并行化算法时遇到了一些问题。目的是对100x100矩阵进行一些修改。当我在没有openMP的情况下运行算法时,一切都在大约34-35秒内顺利运行,当我在2个线程上并行化时(我需要它只有2个线程)它会下降到22秒,但是输出是错误的,我认为它是我无法解决的同步问题。

以下是代码:

for (p = 0; p < sapt; p++){

    memset(count,0,Nc*sizeof(int));

    for (i = 0; i < N; i ++){
        for (j = 0; j < N; j++){

            for( m = 0; m < Nc; m++)
                dist[m] = N+1;

            omp_set_num_threads(2); 
            #pragma omp parallel for shared(configurationMatrix, dist) private(k,m) schedule(static,chunk)
            for (k = 0; k < N; k++){
                for (m = 0; m < N; m++){        

                    if (i == k && j == m)
                        continue;

                    if (MAX(abs(i-k),abs(j-m)) < dist[configurationMatrix[k][m]])
                        dist[configurationMatrix[k][m]] = MAX(abs(i-k),abs(j-m));       
                }
            }   


        int max = -1;

        for(m = 0; m < Nc; m++){

            if (dist[m] == N+1)
                continue;

            if (dist[m] > max){
                max = dist[m];
                configurationMatrix2[i][j] = m;
                }
            }           
        }
    }

    memcpy(configurationMatrix, configurationMatrix2, N*N*sizeof(int));


    #pragma omp parallel for shared(count, configurationMatrix) private(i,j)
    for (i = 0; i < N; i ++)
        for (j = 0; j < N; j++)
            count[configurationMatrix[i][j]] ++;

    for (i = 0; i < Nc; i ++)
        fprintf(out,"%i ", count[i]);
    fprintf(out, "\n"); 
}

其中:sapt = 100; 计数 - &gt;它是一个向量,它包含了我在每一步中所拥有的矩阵的每个元素的数量;

(EX:count[1] = 60 - &gt;我的矩阵中有'1'元素60次,依此类推)

dist --> vector保持距离元素i的最大距离,j表示将值K表示为元素k,m为相同值K.

(EX:dist[1] = 10 - &gt;从值1的元素到值1的最远元素的距离<)

然后我在输出文件中写下了东西,但是输出错误了。

1 个答案:

答案 0 :(得分:1)

如果我在这行中正确理解了您的代码

count[configurationMatrix[i][j]] ++;

在索引为count的元素处递增configurationMatrix[i][j]。我没有看到您的代码采取任何步骤来确保线程不会同时尝试增加count的相同元素。完全可行的是configurationMatrix的两个不同元素向count提供相同的索引,并且这两个元素由不同的线程处理。由于++不是原子操作,因此您的代码具有数据竞争;多个线程可以争用对同一个变量的更新访问,并且您在结果中失去了对正确性或确定性的任何保证。

我认为您的代码的其他部分也可能有其他相同问题的示例。与串行程序的结果相比,您对并行程序的结果中观察到的错误保持沉默,但这些错误在诊断问题时通常非常有用。例如,如果并行程序的结果在每次运行时都不相同,那就非常暗示代码中某处的数据竞争。

如何解决这个问题?由于您只有2个线程,因此最简单的解决方法是不将此部分程序并行化。您可以将数据竞争包装在OpenMP critical部分中,但这实际上只是序列化代码的另一种方式。最后,您可以修改算法和数据结构以完全避免此问题。

相关问题