For loop 有没有一种方法可以控制OpenMP并行_的分区以进行构造?

For loop 有没有一种方法可以控制OpenMP并行_的分区以进行构造?,for-loop,openmp,partitioning,For Loop,Openmp,Partitioning,我使用OpenMP(OMP)并行化for循环。然而,OMP似乎会将我的for循环划分为相等的间隔大小,例如 for( int i = 0; i < n; ++i ) { ... } for(int i=0;i

我使用OpenMP(OMP)并行化for循环。然而,OMP似乎会将我的for循环划分为相等的间隔大小,例如

for( int i = 0; i < n; ++i ) {
 ...
}
for(int i=0;i

NUM\u线程
块,每个块大小
n/NUM\u线程
。不幸的是,我使用它来并行三角矩阵上的扫描,因此最后一个块比第一个块要做更多的工作。所以我真正想问的是在这种情况下如何执行负载平衡。我可以想象,
如果(I%THREAD\u NUMBER==0)
就可以了(换句话说,循环中的每个运行都被分配给不同的线程)。我知道这不是最优的,因为缓存会被破坏,但是,有没有办法用OMP控制循环分区?

有一个子句可以添加到
#pragma OMP for
构造中,它被称为

有了它,您可以指定块(您称之为一个分区)如何分布在线程上

可以找到调度变量的说明。出于您的目的,
dynamic
guided
最适合您


使用
dynamic
时,每个线程获得相同的迭代次数(有一个子句可以添加到
#pragma omp for
构造中,该构造称为

有了它,您可以指定块(您称之为一个分区)如何分布在线程上

可以找到调度变量的说明。出于您的目的,
动态
引导
最适合

使用
dynamic
时,每个线程获得相同的迭代次数(我认为
调度(引导)
在这里是正确的选择。虽然您关于最后一个块有更多工作要做的陈述与我的预期相反,但这取决于您如何进行循环。通常,我会运行类似这样的三角形矩阵

#pragma omp parallel for schedule(guided)
for(int i=0; i<n-1; i++) {
    for(int j=i+1; j<n; j++) {
        //M[i][j]
    }
}
因此,与第一个线程的100次相比,第四个线程只运行了25次。负载不平衡。如果我们切换到
schedule(guided)
,我们会得到:

Thread one   i =  0-24, j =  1-100, j range = 100
Thread two   i = 25-44, j = 26-100, j range = 75
Thread three i = 45-69, j = 46-100, j range = 55
Thread four  i = 60-69, j = 61-100, j range = 40
Thread one   i = 70-76, j = 71-100
...
现在第四个线程运行了40次,而第1个线程运行了100次。这仍然不是均衡的,但要好得多。但是随着调度程序继续进行进一步的迭代,平衡会变得更好,所以它会收敛到更好的负载平衡。

我认为
调度(指南)
在这里是正确的选择。虽然您关于最后一个块有更多工作要做的陈述与我的预期相反,但这取决于您如何进行循环。通常,我会运行类似这样的三角形矩阵

#pragma omp parallel for schedule(guided)
for(int i=0; i<n-1; i++) {
    for(int j=i+1; j<n; j++) {
        //M[i][j]
    }
}
因此,与第一个线程的100次相比,第四个线程只运行了25次。负载不平衡。如果我们切换到
schedule(guided)
,我们会得到:

Thread one   i =  0-24, j =  1-100, j range = 100
Thread two   i = 25-44, j = 26-100, j range = 75
Thread three i = 45-69, j = 46-100, j range = 55
Thread four  i = 60-69, j = 61-100, j range = 40
Thread one   i = 70-76, j = 71-100
...
现在,第四个线程运行了40次,而第1个线程运行了100次。这仍然不是均衡的,但它要好得多。但是随着调度程序继续进行进一步的迭代,平衡会变得更好,因此它会收敛到更好的负载平衡