Parallel processing 依赖关系图
我做了一些以前的OpenMP练习进行了一点练习,但我很难找到解决方法,尤其是on 目标是编写与依赖关系图对应的最简单的OpenMP代码 图可见于此: 第一个很简单。Parallel processing 依赖关系图,parallel-processing,openmp,dependency-graph,Parallel Processing,Openmp,Dependency Graph,我做了一些以前的OpenMP练习进行了一点练习,但我很难找到解决方法,尤其是on 目标是编写与依赖关系图对应的最简单的OpenMP代码 图可见于此: 第一个很简单。 #pragma omp parallel { #pragma omp simple { #pragma omp task { A1(); } #pragma omp task { B1(); } #pragma omp task { C1();
#pragma omp parallel
{
#pragma omp simple
{
#pragma omp task
{
A1();
}
#pragma omp task
{
B1();
}
#pragma omp task
{
C1();
}
#pragma omp barrier
A2();
B2();
C2();
}
}
它对应于以下代码:
#pragma omp parallel
{
#pragma omp simple
{
#pragma omp task
{
A1();
A2();
}
#pragma omp task
{
B1();
B2();
}
#pragma omp task
{
C1();
C2();
}
}
}
第二个仍然很容易。
#pragma omp parallel
{
#pragma omp simple
{
#pragma omp task
{
A1();
}
#pragma omp task
{
B1();
}
#pragma omp task
{
C1();
}
#pragma omp barrier
A2();
B2();
C2();
}
}
现在是最后一个…
这让我有点烦,因为依赖项的数量在所有函数调用中都是不相等的。我认为有一种方法可以明确说明您应该等待哪个任务,但我在OpenMP文档中找不到我想要的
如果有人对这个问题有任何解释,我将非常感激,因为我已经考虑了一个多月了。首先,OpenMP 4.5规范中没有
#pragma omp simple
。
我想你是指#pragma omp single
如果是这样的话,pragma omp barrier
在单个
区域内是个坏主意,因为只有一个线程将执行代码并等待所有其他线程,而这些线程不执行该区域
此外,在A2上的第二种情况下,B2和C2不再作为任务并行执行
对于您的实际问题:
您正在寻找的似乎是位于的任务构造的depend
子句
Massimiliano对depend子句及其工作原理有一个很好的解释。最后一个例子在你理解了那里发生的事情后就不那么复杂了:每个任务
Tn
都取决于上一次迭代T-1\n
及其邻居(T-1\n-1
和T-1\n+1
)。这种模式称为。这在偏微分方程求解器中非常常见
正如亨克斯曼所说,最简单的选择是使用OpenMP任务的depend
子句:
int val_a[N], val_b[N];
#pragma omp parallel
#pragma omp single
{
int *a = val_a;
int *b = val_b;
for( int t = 0; t < T; ++t ) {
// Unroll the inner loop for the boundary cases
#pragma omp task depend(in:a[0], a[1]) depend(out:b[0])
stencil(b, a, i);
for( int i = 1; i < N-1; ++i ) {
#pragma omp task depend(in:a[i-1],a[i],a[i+1]) \
depend(out:b[i])
stencil(b, a, i);
}
#pragma omp task depend(in:a[N-2],a[N-1]) depend(out:b[N-1])
stencil(b, a, N-1);
// Swap the pointers for the next iteration
int *tmp = a;
a = b;
b = tmp;
}
#pragma omp taskwait
}
int val_a[N],val_b[N];
#pragma-omp并行
#布拉格omp单曲
{
int*a=val_a;
int*b=val_b;
对于(int t=0;t
正如您可能看到的,OpenMP任务依赖关系是点对点的,这意味着您不能用数组区域来表示它们
另一个选项(对于这种特定情况来说更简洁)是使用屏障间接强制依赖关系:
int a[N], b[N];
#pragma omp parallel
for( int t = 0; t < T; ++t ) {
#pragma omp for
for( int i = 0; i < N-1; ++i ) {
stencil(b, a, i);
}
}
inta[N],b[N];
#pragma-omp并行
对于(int t=0;t
第二种情况在每次内部循环完成时执行同步屏障。同步粒度更粗,因为每个外部循环迭代只有一个同步点。但是,如果模具
函数很长且不平衡,则可能值得使用任务