OpenMP 4.5 任务依赖关系和执行顺序

OpenMP 4.5 task dependencies and execution order

本文关键字:执行 顺序 关系 依赖 任务 OpenMP      更新时间:2023-10-16

我试图让 OpenMP 任务依赖项工作,但无济于事。 让我们以这个简化的例子为例:

int main()
{
int x=0;
#pragma omp parallel
#pragma omp single
{
#pragma omp task depend(in:x)
{
#pragma omp critical
cout << "Read the value " << x << "n";
}
#pragma omp task depend(out:x)
{
x = 3;
#pragma omp critical
cout << "Set the value to " << x << "n";
}
}
return 0;
}

据我了解(来自 OpenMP 规范(,依赖(in:x( 任务应该只在所有依赖(out:x(任务都解决后执行,因此预期的输出是

Set the value to 3
Read the value 3

但是,任务是按语义顺序执行的,忽略了依赖子句,我得到的是这样的:

Read the value 0
Set the value to 3

我正在使用带有 -fopenmp 标志的 g++-7 (SUSE Linux( 7.3.1 20180323 [gcc-7-branch 修订版 258812] 进行编译。此版本的编译器应有权访问 OpenMP 4.5。

这是对我这边任务依赖关系的误解,还是这里还有其他东西在起作用?

任务依赖关系的概念可能会产生误导。

最好的表达方式是将它们视为指示不同任务如何访问数据的一种方式,而不是控制执行顺序的一种方式。

源代码中任务的顺序以及 depende 子句描述了 4 种可能的情况之一:写后读、读后写、写后和读后读

在您的示例中,您描述了读取后写入的情况:您告诉编译器第二个任务将覆盖变量 x,但第一个任务将 x 作为输入,如depend(in:x)所示。因此,软件将在第二个任务之前执行第一个任务,以防止覆盖初始值。

如果您查看英特尔的文档,这里有一个简短的示例,其中显示了任务顺序(在源代码中(如何在确定依赖关系图(因此,在执行顺序(中发挥作用。

有关此问题的另一个信息页面可在此处获得。