OpenMP 并行等待

Posted

技术标签:

【中文标题】OpenMP 并行等待【英文标题】:OpenMP parallel nowait 【发布时间】:2016-05-30 20:37:20 【问题描述】:

OpenMP 有没有办法消除parallel 块上的障碍?

我知道nowait 可以在parallel 内的forsections 块中使用,以便允许线程继续前进,而不必等待所有线程完成相关块。但是,#pragma omp parallel nowait 会产生编译器错误。

我正在开发一个带有 UI 的程序。我调用一个函数来加载 UI,同时,我还想与服务器取得联系以发送一些使用数据。

这些功能中的每一个都可以正常工作,但如果我不并行执行它们,则需要一段时间。如果服务器已关闭,则连接尝试可能需要几秒钟才能中止,然后简单地加载 UI 也需要一秒钟,此时事情花费的时间太长了。首先加载 UI,然后进行连接会使 UI 看起来冻结。

所以我想做类似的事情

// this generates a compiler error
#pragma omp parallel num_threads(2) nowait

  if(omp_get_thread_num() == 0)
    LoadUI();
  else
    Connect();

这样,主线程(必须是加载 UI 的线程)将加载 UI,然后继续前进,而不管任何连接问题。但是,由于parallel nowait 被禁止,据我了解,如果由于parallel 末尾的隐式屏障而出现连接问题(中止所需的时间比加载 UI 所需的时间更长),程序仍将暂时挂起.

有没有办法解决这个问题?我真正想做的是在程序继续运行时请求一个新线程来进行连接,而不管线程做什么或完成需要多长时间(显然,线程不会触及主使用的任何数据线程)。

【问题讨论】:

【参考方案1】:

我认为您尝试做的事情与 OpenMP fork-join 模型不兼容。这个想法是在每个并行区域中生成在并行区域末端连接的线程。好的,线程并没有实际上产生,因为通常有一个线程池,但这是概念模型。

请注意,即使以下内容也会产生编译器错误:

#pragma omp parallel for nowait
for (i=0; i<10; i++) 
  ...

你可以做的是避开for之后的障碍,一个平行区域。例如:

#pragma omp parallel

    #pragma omp parallel for
    for (int i=0; i<2; i++) 
    
    /* no wait here */
    #pragma omp for
    for (int i=0; i<2; i++) 
    

要执行您需要的操作,您可能必须使用 pthread 或线程库。

PS:您可以使用 OpenMP 部分而不是检查线程 ID。

【讨论】:

"PS:如果 OP 需要 GUI 线程执行某些操作,您可以使用 OpenMP 部分而不是检查线程 id。" 甚至 omp master跨度> 谢谢,我担心会是这样。事实上,考虑 fork-join 模型就很清楚了。没想到我。关于使用部分,我需要在主线程中调用CreateUI(),我的理解是部分不能保证哪个线程做什么。 @PiotrSkotnicki,但如果我使用master 调用CreateUI(),主线程将继续运行不在该块中的任何内容,因此重复调用@987654328 @,不是吗?

以上是关于OpenMP 并行等待的主要内容,如果未能解决你的问题,请参考以下文章

OpenMP 并行用于 - 多个并行用于的 Vs。一个并行,其中包含多个 for

openMP 嵌套并行 for 循环与内部并行 for

OpenMP:嵌套并行化有啥好处?

OpenMp实现并行化

openMP:并行运行所有线程会导致内存不足异常

为啥 OpenMP 不并行化 vtk IntersectWithLine 代码