计数在 OpenMP 中无法正常工作

Counting does not work properly in OpenMP

我有这个功能

void collatz(int startNumber, int endNumber, int* iter, int nThreads)
{
    int i, n, counter;
    int isodd; /* 1 if n is odd, 0 if even */
    #pragma omp parallel for
    for (i = startNumber; i <= endNumber; i++)
    {
        counter = 0;
        n = i;
        omp_set_num_threads(nThreads);
        while (n > 1)
        {
            isodd = n%2;
            if (isodd)
                n = 3*n+1;
            else
                n/=2;
            counter++;
        }
        iter[i - startNumber] = counter;
    }
}

它在 运行 串行时如我所愿地工作(即在没有 OpenMP 的情况下编译或注释掉 #pragma omp parallel foromp_set_num_threads(nThreads);)。然而,并行版本产生了错误的结果,我认为这是因为 counter 变量需要在每个 for 循环开始时设置为零,也许另一个线程可以使用非零 counter 价值。但是即使我使用#pragma omp parallel for private(counter),问题仍然存在。我错过了什么?

我把程序编译成C89。

在您的 OpenMP 并行区域中,您正在为 counternisodd 标量变量赋值。因此,它们不能像默认情况下那样只是 shared。你需要格外注意它们。

快速分析表明,由于它们的值仅在并行区域内且仅对当前线程有意义,因此很明显需要声明它们 private

#pragma omp parallel 指令中添加 private( counter, n, isodd ) 子句应该可以解决问题。