鉴于此代码示例,练习是使用任务与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
可以避免吗?
答案 0 :(得分:1)
您可以使用reduction
来计算“好”项目。以下代码将为您完成工作。您可能需要阅读this for reduction和this 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)
您必须明确声明n
为shared
,否则默认为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上。