OpenMP:foo()和bar()有什么区别?

3
void foo(void) {
    #pragma omp parallel
    {
        #pragma omp single
            {fprintf(stderr, "first part\n"); }
        #pragma omp barrier   
        #pragma omp single
           { fprintf(stderr, "second part\n"); }
    }
}
void bar (void) {
    #pragma omp parallel
    {
        #pragma  omp sections
        {
            fprintf(stderr, "first part\n"); 
             #pragma  omp section
             fprintf(stderr, "second part\n"); 
         }
    }
}

Q1- foo()和bar()是否等效?


我猜想,由于你在问题中使用了“Q1”,这可能是来自某个教程或作业。 - Svante
我曾经作为一项研究提出过那个问题!! - Asma Hamdy
2个回答

5
它们不是等价的。 foo() 会依次执行两个 fprintf(部分)。bar() 可能会并行执行它们。
如果您需要详尽的参考资料,请参阅IBM 编译器文档
foo() 的情况下,单个工作线程处理 first part,然后完成并与主线程重新同步(顺便说一下,在 single 构造的末尾隐含了一个屏障)。然后新的工作线程处理 second part,完成并重新与主线程同步。
bar() 的情况下,每个段(第一段 first part 是一个隐含段)由单独的工作线程处理。工作线程并行完成工作。

#pragma omp parallel

omp parallel 指令显式指示编译器并行化所选代码块。遇到并行区域时,形成一个逻辑线程组。团队中的每个线程都执行并行区域中的所有语句,除了工作共享结构外。在团队中,在工作共享结构之前,工作被分配给各个线程。

循环迭代必须独立于循环才能并行化。在并行化的语句块末尾隐含有一个屏障。

嵌套并行区域始终是串行的。

#pragma omp single

omp single 指令标识必须由单个可用线程运行的代码段。

在并行化的语句块末尾,存在一个隐含的屏障,除非指定了 nowait 子句。

#pragma omp section, #pragma omp sections

omp sections 指令将工作分发给绑定到已定义并行区域的线程。

对于 omp sections 指令内的第一个程序代码段,omp section 指令是可选的。后续段必须以 omp section 指令为前缀。所有 omp section 指令必须出现在与 omp sections 指令相关联的程序源代码段的词法结构中。

当程序执行到达 omp sections 指令时,由以下 omp section 指令定义的程序段将在可用线程之间进行并行执行。在与 omp sections 指令相关联的更大程序区域的末尾隐含定义了一个屏障,除非指定了 nowait 子句。


2
这段文字提到了一些关于OpenMP的记忆,同时还引用了一个资源作为帮助。
  • SECTION指令“指定任意顺序代码块的并行执行。每个SECTION由团队中的一个线程执行一次。”

  • SINGLE指定一个代码块,“只允许一个线程执行该代码;未被选中执行此部分的线程将忽略该代码。”

  • BARRIER指令强制所有线程在该点相遇,从而产生一个阻塞,直到所有线程都赶上。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接