在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)
显示这两个部分正在由不同的线程执行.
值得注意的是,然而这段代码无法提取比两个线程更多的并行性:如果它是用更多线程执行的,那么其他线程没有任何工作要做,只会闲置.
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.输出顺序是非确定性的,因为您不知道首先运行什么线程.
小智 12
改变第一行
#pragma omp部分
成
#pragma omp parallel sections
"parallel"指令确保将两个部分分配给两个线程.然后,您将收到以下输出id = 0,id = 1,
根据OpenMP 标准 3.1 的第 2.5.2 节(重点是我的):
部分构造是一种非迭代工作共享构造,它包含一组结构化块,这些块将在团队中的线程之间分发并由其执行。每个结构化块 由团队中的线程之一在其隐式任务的上下文中执行一次。
...
sections 构造中的每个结构化块前面都有一个section 指令,除了第一个块之外,前面的section 指令是可选的。在组中的线程之间调度结构化块的方法是实现定义的。除非指定 nowait 子句,否则在节构造的末尾有一个隐式屏障。
因此,将这些规则应用于您的案例,我们可以认为:
sections指令中标识的不同结构块由一个线程执行一次。换句话说,无论线程数如何,您总是有四次打印sections执行(以非确定性顺序)。这是因为工作共享结构末尾的隐含障碍sections因此,您的输出取决于您的调度程序决定将不同块分配给团队中的线程的方式。