2

鉴于此代码示例,练习是使用任务将代码与 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吗?

4

2 回答 2

2

您可以使用reduction计数“好”项目。以下代码将为您完成这项工作。你可能想阅读这个来减少这个遍历链表

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;
            }
        }           
    }
}
于 2013-02-19T09:55:38.433 回答
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 上,该构造的开销比原子增量高得多。

于 2013-02-19T12:21:40.527 回答