OpenMP中的SECTIONS指令如何分配?

kar*_*kar 39 openmp

在OpenMP中使用时omp sections,将线程分配到这些块内的部分,或者将每个线程被分配给每个区段?

时间nthreads == 3:

#pragma omp sections
{
    #pragma omp section
    { 
        printf ("id = %d, \n", omp_get_thread_num());
    }

    #pragma omp section
    { 
        printf ("id = %d, \n", omp_get_thread_num());
    }
}
Run Code Online (Sandbox Code Playgroud)

输出:

id=1
id=1
Run Code Online (Sandbox Code Playgroud)

但是当我执行以下代码时:

#pragma omp sections
{
    #pragma omp section
    { 
        printf ("id = %d, \n", omp_get_thread_num());
    }

    #pragma omp section
    { 
        printf ("id = %d, \n", omp_get_thread_num());
    }
}

#pragma omp sections
{
    #pragma omp section
    { 
        printf ("id = %d, \n", omp_get_thread_num());
    }

    #pragma omp section
    { 
        printf ("id = %d, \n", omp_get_thread_num());
    }
}
Run Code Online (Sandbox Code Playgroud)

输出:

id=1
id=1

id=2
id=2
Run Code Online (Sandbox Code Playgroud)

从这些输出中我无法理解OpenMP中各节的概念.

Spo*_*ock 93

OP发布的代码永远不会并行执行,因为parallel关键字不会出现.OP得到的ID与0不同的事实表明,他的代码可能嵌入在并行指令中.然而,他的帖子并不清楚这一点,可能会让初学者感到困惑.

最简单的例子是(对于OP发布的第一个例子):

#pragma omp parallel sections
{
    #pragma omp section
    { 
        printf ("id = %d, \n", omp_get_thread_num());
    }

    #pragma omp section
    { 
        printf ("id = %d, \n", omp_get_thread_num());
    }
}
Run Code Online (Sandbox Code Playgroud)

在我的机器上,这打印

id = 0,
id = 1,
Run Code Online (Sandbox Code Playgroud)

显示这两个部分正在由不同的线程执行.

值得注意的是,然而这段代码无法提取比两个线程更多的并行性:如果它是用更多线程执行的,那么其他线程没有任何工作要做,只会闲置.

  • 这个答案没有解释为什么OP显示“id=1”和“id=2”。OP 发布的程序很可能是并行运行的。 (2认同)

wum*_*ump 26

并行部分的想法是给编译器一个提示,即各个(内部)部分可以并行执行,例如:

#pragma omp parallel sections
{
   #pragma omp section
   {
      /* Executes in thread 1 */
   } 
   #pragma omp section
   {
      /* Executes in thread 2 */
   } 
   #pragma omp section
   {
      /* Executes in thread 3 */
   } 
   /* ... */
}
Run Code Online (Sandbox Code Playgroud)

这是对编译器的暗示,但不保证会发生,尽管应该如此.你的输出是预期的; 它表示在线程ID 1和线程2中执行#sections.输出顺序是非确定性的,因为您不知道首先运行什么线程.

  • -1 你的回答有很多不准确之处。您不能确定将不同的部分分配给不同的线程。输出顺序仅在单个 `sections` 构造内是不确定的,而不是在两个不同的 `sections` 之间(构造末尾的隐式障碍) (2认同)

小智 12

改变第一行

#pragma omp部分

#pragma omp parallel sections

"parallel"指令确保将两个部分分配给两个线程.然后,您将收到以下输出id = 0,id = 1,


Cha*_*how 9

你缺少parallel关键字.该parallel关键字并行触发openmp运行.


Mas*_*ano 7

根据OpenMP 标准 3.1 的第 2.5.2 节(重点是我的):

部分构造是一种非迭代工作共享构造,它包含一组结构化块,这些块将在团队中的线程之间分发并由其执行。每个结构化块 由团队中的线程之一在其隐式任务的上下文中执行一次。

...

sections 构造中的每个结构化块前面都有一个section 指令,除了第一个块之外,前面的section 指令是可选的。在组中的线程之间调度结构化块的方法是实现定义的。除非指定 nowait 子句,否则在节构造的末尾有一个隐式屏障。

因此,将这些规则应用于您的案例,我们可以认为:

  1. sections指令中标识的不同结构块由一个线程执行一次。换句话说,无论线程数如何,您总是有四次打印
  2. 第一个中的块将在第二个中的块(也以非确定性顺序执行)之前sections执行(以非确定性顺序)。这是因为工作共享结构末尾的隐含障碍sections
  3. 调度是实现定义的,因此您无法控制哪个线程已分配给给定的部分

因此,您的输出取决于您的调度程序决定将不同块分配给团队中的线程的方式。