我正在使用OpenMP,我希望生成线程,以便一个线程执行一段代码并完成,同时运行并行循环迭代的N个线程。
执行应该是这样的:
Section A (one thread) || Section B (parallel-for, multiple threads)
| || | | | | | | | | | |
| || | | | | | | | | | |
| || | | | | | | | | | |
| || | | | | | | | | | |
| || | | | | | | | | | |
V || V V V V V V V V V V我不能只使用#pragma omp once编写并行-for,因为我不希望执行A部分的线程执行for-循环。
我试过这样做:
#pragma omp parallel sections {
#pragma omp section
{
// Section A
}
#pragma omp section
{
// Section B;
#pragma omp parallel for
for (int i = 0; i < x; ++i)
something();
}
}但是,并行-for总是只执行一个线程(我知道,因为我创建了循环打印omp_get_thread_num()的主体,它们都是相同的数字,取决于两个线程执行第二个并行部分的线程是1还是0)。
我也试过
#pragma omp sections {
#pragma omp section
{
// Section A
}
#pragma omp section
{
// Section B;
#pragma omp parallel for
for (int i = 0; i < x; ++i)
something();
}
}它允许for-循环使用多个线程执行,但它使各节非并行,第一节在第二节之前按顺序执行。
我需要的是这两种方法的结合,其中for-循环和第一节的每一次迭代都是并行运行的。
发布于 2014-04-20 08:06:46
嵌套并行必须显式设置,因为在大多数实现中它默认是禁用的。按照OpenMP 4.0标准,必须设置OMP_NESTED环境变量:
OMP_NESTED环境变量通过设置nested ICV的初始值来控制嵌套并行。此环境变量的值必须为true或false。如果环境变量设置为true,则启用嵌套并行;如果设置为false,则禁用嵌套并行。如果OMP_NESTED的值既不是真也不是假,那么程序的行为就是实现定义的。
下面一行应该适用于bash:
export OMP_NESTED=true此外,正如@HristoIliev在下面的评论中所指出的,您很可能希望设置OMP_NUM_THREADS环境变量来优化性能。引用标准:
此环境变量的值必须是正整数值的列表。列表的值在相应的嵌套级别上设置用于并行区域的线程数。
这意味着应该设置OMP_NUM_THREADS的值,类似于n,n-1,其中n是CPU核心的数量。例如:
export OMP_NUM_THREADS=8,7对于8核系统(例如,从下面的注释复制)。
发布于 2014-04-20 06:17:48
也许下面的代码可以做到这一点:
#pragma omp parallel for
for (int i = -1; i < x; ++i) {
if (i==-1) {
// Section A
}
else {
// Section B
something();
}
}但是,您需要确保x >= 0。
发布于 2017-04-22 08:52:56
你有没有尝试过一个有差异的平行区域。不应该需要嵌套并行。
#pragma omp_parallel
{
#pragma omp task
once();
#pragma omp for
for(int i=0;i<N;i++){
many(i);
}
}您还可以在并行区域中使用基于线程的显式if / else,并为第二个循环自己进行工作共享计算。
https://stackoverflow.com/questions/23178183
复制相似问题