循环中缺少错误(带有C的OpenMP)

时间:2017-02-12 21:49:40

标签: c parallel-processing openmp

int count1(testcase *testcases, int n) {
    int i;
    int count = 0;
    #pragma omp parallel for
    for (i = 0; i < n; ++i) {
        if (test(testcases[i]) == true) {
        ++count;
        }
    }
    return count;
}

有点不寻常的问题,即似乎没有问题。 自学OpenMP for C,这是关于我正在阅读的主题的PDF。

作者暗示代码存在一些问题。给定n个测试用例,我们进行了一些功能测试,对案例做了一些事情并给出了一个布尔值,表明测试是否成功。这段代码应该计算测试次数。作者说,它确实错误 - 我只是不明白为什么。一直试图把我的思绪包围一段时间,这可能很简单。

我一直在尝试使用0和1的数组编写一个这样的示例版本并替换

test(testcases[i]) == true

通过表达式检查它是否为1并计算它。但是,它正确计算了我的1s。哪里出错了?

1 个答案:

答案 0 :(得分:0)

这是交易,这个代码可以执行得很好,但问题是计数变量,它被声明在并行区域之外(也就是循环),然后在并行区域内递增。因此,计数增加并行运行会产生问题,因为如果两个或多个线程同时尝试增加计数,因为相信我会发生这种情况。那么奇怪的事情就会开始发生。

变量存储在内存中,所以为了增加变量的值,我们需要从内存中读取它(当前值),在CPU中增加它并将其写回。现在我们并行运行这个序列,所以有时会发生这种情况(记住并行运行的线程):

  1. 内存计数= 2
  2. 线程1读取count(2)
  3. 线程2读取count(2)
  4. 线程1增加并写回内存中的count变量(3)
  5. 同样的事情是线程2(写回3)
  6. 所以现在在内存中我们在count变量中有3个值,但由于两个线程被执行,它应该是4.这就是为什么这个代码不会总是工作的原因。这只是可能发生的事情之一。这就是为什么我们知道关键部分,信号量,互斥体,...希望这会有所帮助。