【问题标题】:Openmp synchronizing within parallel forOpenmp在并行内同步
【发布时间】:2012-11-07 20:55:40
【问题描述】:

我需要做这样的事情

#pragma omp parallel{

#pragma omp for
for_1(){

   for_2(){
     do_something();
   }
   #pragma omp barrier //wait for all threads to finish after the inner for

   continue_with_something_else_in parallel();

}

}

编译器告诉我不能在那里设置障碍。有谁知道我该如何解决这个问题?

【问题讨论】:

  • 编译器是正确的(通常是这样)。如果不同的线程在 for 循环中执行不同数量的迭代,它们将遇到不同数量的障碍——这将如何工作?你可以考虑使用flush 来确保所有线程对共享变量有一个共同的看法,但是考虑到并行 for 循环中的东西应该是独立的,我对任何需要它们的算法都深表怀疑内部 for 循环之后的内存的常见视图,同样,并非所有线程都会执行相同的次数。你到底想做什么?
  • 好的,我现在明白了。事情是修改一些共享数组的内部,并且在屏障之后所有线程都需要使用这些数组的值。
  • 那么也许flush指令可以工作?
  • 有可能,但请仔细阅读文档;冲洗并不总是如您所想。

标签: c multithreading parallel-processing synchronization openmp


【解决方案1】:

我知道这是一篇旧帖子,但既然我发现了它,其他人可能也会...

解决方案:

#pragma omp parallel
{

#pragma omp for schedule(static)
   for_1() {
      for_2() {
        do_something();
      }
   }
   // note implicit barrier after for construct

#pragma omp for shedule(static)
   for_1() {
      continue_with_something_else_in parallel();
   }

}

说明:

OpenMP 在“块”中调度 for 循环并将它们分配给线程,这意味着在一次循环迭代中拥有 barrier 将是有问题的,因为 正在等待的同一线程可能是还分配了一些其他循环迭代,因此它将在死锁状态中等待自己。

但 OpenMP 标准确实保证,如果您使用 schedule(static),单个 parallel 主体中的相同线程被分配相同的循环迭代,并且可以有效地共享内存,这就是我所做的。

【讨论】:

    【解决方案2】:

    也许这个链接会对你有所帮助:

    http://publib.boulder.ibm.com/infocenter/lnxpcomp/v8v101/index.jsp?topic=%2Fcom.ibm.xlcpp8l.doc%2Fcompiler%2Fref%2Fruompbar.htm

    据我所知:

    omp 屏障指令必须出现在块或复合语句中。例如:

    if (x!=0) {
       #pragma omp barrier    /* valid usage    */
    }
    if (x!=0)
       #pragma omp barrier    /* invalid usage  */
    

    【讨论】:

    • 嗯,这是什么意思?屏障在并行范围内,但是当我编译时出现此错误错误:屏障区域可能没有紧密嵌套在工作共享、关键、有序、主或显式任务区域内
    • 编译器说明一切:屏障区域可能不在工作共享任务内。 #pragma omp for 是一项工作共享任务。查看我在“#pragma omp for”上发布的链接
    • 我想我现在明白了。谢谢!
    猜你喜欢
    • 2013-04-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-04
    • 1970-01-01
    • 2012-06-20
    • 1970-01-01
    • 2015-08-18
    相关资源
    最近更新 更多