我正在学习使用C和OpenMP进行并行编程。我想编写一个简单的代码,其中多个线程会递增两个共享值。首先,我使用了reduction指令,并且它按照预期工作。然后,我切换到使用critical指令来启动关键部分 - 它也起作用了。出于好奇心,我尝试合并这两个解决方案并检查行为。我期望得到两个有效的、相等的值。
代码:
#include <stdio.h>
#include <stdlib.h>
#include "omp.h"
#define ITER 50000
int main( void )
{
int x, y;
#pragma omp parallel reduction(+:x,y)
{
#pragma omp for
for (int i = 0; i < ITER; i++ )
{
x++;
#pragma omp critical
y++;
}
}
printf("non critical = %d\ncritical = %d\n", x, y);
return 0;
}
输出:
非关键 = 50000
关键 = 4246432
当涉及到 'critical'(变量y)时,输出当然是随机的,而另一个则如预期般始终为50000。
x的行为是可以理解的——reduction使其在单个线程的范围内私有化。在增量值从线程中汇总并传递到非本地x之后。
我不明白的是y的行为。它与x一样是私有的,但它也位于critical部分中,因此它“有多个原因”无法被其他线程访问。然而,我认为发生了竞争条件。 critical是否以某种方式使y公开(共享)?
我知道这段代码没有意义,因为只使用reduction / critical之一就足够了。我只想知道背后的行为是什么。
reduction
指令中自动完成(对于 + 和 - 为 0,对于 * 和 / 为 1)。 - user4433856