重复的线程在它们应该是唯一的时候出现(OpenMP)

Duplicate threads showing up when they should be unique (OpenMP)

我必须编写一个代码来计算部分和:S(i) = Σ a(j)(j 从 0 到 i)。每次,我都必须在循环中显示 S(i)(代码中名为 somme)的值,并且我必须使用 OpenMP 对其进行编码。这是我的代码:

#include <stdio.h>
#include <omp.h>
#define n 16

int main(void) {
    int a[n] = {2,3,6,9,4,7,0,2,2,6,8,9,11,0,2,4};
    int i, j, t, somme;

    #pragma omp parallel num_threads(16)
    #pragma omp for
    for (i=0; i<n; i++){
        t = omp_get_thread_num();
        somme = a[0];
        for (j=1; j<i+1; j++) somme += a[j];
        printf("<%d>: S(%d) = %d\n", t, i, somme);
    }
    return 0;
}

但是,当我运行 16个线程的代码时,一些线程是重复的,那些线程的结果是错误的:

  <15>: S(15) = 75
  <7>: S(7) = 33
  <6>: S(2) = 11
  <6>: S(6) = 31
  <8>: S(8) = 35
  <9>: S(9) = 41
  <10>: S(10) = 49
  <11>: S(11) = 58
  <14>: S(14) = 71
  <12>: S(12) = 69
  <14>: S(13) = 69
  <5>: S(5) = 35
  <3>: S(3) = 20
  <0>: S(0) = 2
  <5>: S(1) = 35
  <4>: S(4) = 24

我问过我的教授,他不知道发生了什么事。我不明白为什么我的代码会这样,有人可以帮助我吗?

如@EOF 所述,由于共享变量 (i,j,t,somme),您存在数据竞争。您必须将它们设为私有:

#pragma omp for private(i,j,t,somme)

如果您在变量的最小要求范围内定义变量,效果会更好:

int main(void) {
    int a[n] = {2,3,6,9,4,7,0,2,2,6,8,9,11,0,2,4};

    #pragma omp parallel num_threads(16)
    #pragma omp for
    for (int i=0; i<n; i++){
        int t = omp_get_thread_num();
        int somme = a[0];
        for (int j=1; j<i+1; j++) somme += a[j];
        printf("<%d>: S(%d) = %d\n", t, i, somme);
    }
    return 0;
}