首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用一个线程执行区段,用多个线程执行for循环。

使用一个线程执行区段,用多个线程执行for循环。
EN

Stack Overflow用户
提问于 2014-04-20 03:43:32
回答 3查看 1.5K关注 0票数 5

我正在使用OpenMP,我希望生成线程,以便一个线程执行一段代码并完成,同时运行并行循环迭代的N个线程。

执行应该是这样的:

代码语言:javascript
复制
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-循环。

我试过这样做:

代码语言:javascript
复制
#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)。

我也试过

代码语言:javascript
复制
#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-循环和第一节的每一次迭代都是并行运行的。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2014-04-20 08:06:46

嵌套并行必须显式设置,因为在大多数实现中它默认是禁用的。按照OpenMP 4.0标准,必须设置OMP_NESTED环境变量:

OMP_NESTED环境变量通过设置nested ICV的初始值来控制嵌套并行。此环境变量的值必须为true或false。如果环境变量设置为true,则启用嵌套并行;如果设置为false,则禁用嵌套并行。如果OMP_NESTED的值既不是真也不是假,那么程序的行为就是实现定义的。

下面一行应该适用于bash:

代码语言:javascript
复制
 export OMP_NESTED=true

此外,正如@HristoIliev在下面的评论中所指出的,您很可能希望设置OMP_NUM_THREADS环境变量来优化性能。引用标准:

此环境变量的值必须是正整数值的列表。列表的值在相应的嵌套级别上设置用于并行区域的线程数。

这意味着应该设置OMP_NUM_THREADS的值,类似于n,n-1,其中n是CPU核心的数量。例如:

代码语言:javascript
复制
export OMP_NUM_THREADS=8,7

对于8核系统(例如,从下面的注释复制)。

票数 2
EN

Stack Overflow用户

发布于 2014-04-20 06:17:48

也许下面的代码可以做到这一点:

代码语言:javascript
复制
#pragma omp parallel for
for (int i = -1; i < x; ++i) {
    if (i==-1) {
        // Section A
    }
    else {
        // Section B
        something();
    }
}

但是,您需要确保x >= 0。

票数 0
EN

Stack Overflow用户

发布于 2017-04-22 08:52:56

你有没有尝试过一个有差异的平行区域。不应该需要嵌套并行。

代码语言:javascript
复制
#pragma omp_parallel 
{

#pragma omp task  
  once();

#pragma omp for 
  for(int i=0;i<N;i++){
    many(i);
  }

}

您还可以在并行区域中使用基于线程的显式if / else,并为第二个循环自己进行工作共享计算。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/23178183

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档