OpenMP:任务中的竞争条件

时间:2013-02-18 23:24:35

标签: c multithreading parallel-processing openmp

鉴于此代码示例,练习是使用任务与OpenMP 并行代码。这是一组项目,我们想要计算好的项目。

int count_good (item_t* item)
{
    int n = 0;
    while (item) {
       if (is_good(item))
          n++;
       item = item->next;
    }
    return n;
}

这不完全是家庭作业。这是为了考试的准备。我的想法如下:

int count_good (item_t* item)
{
    int n = 0;
    while (item) {
       #pragma omp task
       {
       if (is_good(item))
          n++;
       }
       item = item->next;
    }
    #pragma omp taskwait
    return n;
}
...

int main ()
{
...
#pragma omp parallel
{
#pragma omp single
    count_good(some_times);
}
}

问题是n,它是单个线程的私有变量,但它可以同时通过不同的任务增加。这会产生竞争条件吗?使用#pragma omp critical可以避免吗?

2 个答案:

答案 0 :(得分:1)

您可以使用reduction来计算“好”项目。以下代码将为您完成工作。您可能需要阅读this for reductionthis for traversing linked list

int nCount = 0;
#pragma omp parallel reduction(+ : nCount)
{       
    for(struct item_t *listWalk = some_items; listWalk != NULL; 
      listWalk = listWalk->next)
    {
        #pragma omp single nowait
        {
            if( isGood(listWalk) ){
            nCount += 1;
            }
        }           
    }
}

答案 1 :(得分:1)

您必须明确声明nshared,否则默认为firstprivate(因为它在封闭的上下文中隐式private)。然后,为了确保n的原子增量,您应该应用atomic update构造。最后,您的代码应如下所示:

int count_good (item_t* item)
{
    int n = 0;
    while (item) {
       #pragma omp task shared(n)
       {
       if (is_good(item))
          #pragma omp atomic update
          n++;
       }
       item = item->next;
    }
    #pragma omp taskwait
    return n;
}

critical构造的开销比原子增量高得多,至少在x86上。