如何让 OpenMP 在程序每次运行时只创建一次线程?

Posted

技术标签:

【中文标题】如何让 OpenMP 在程序每次运行时只创建一次线程?【英文标题】:How do I ask OpenMP to create threads only once at each run of the program? 【发布时间】:2011-11-15 06:55:21 【问题描述】:

我正在尝试并行化由第三方编写的大型程序。我不能透露代码,但我会尝试给出我想做的最接近的例子。 基于下面的代码。如您所见,由于“并行”子句位于 while 循环内部,因此每次迭代都会完成线程的创建/销毁,这是昂贵的。 鉴于我无法将 Initializors...等移到“while”循环之外。

--基础代码

void funcPiece0()

    // many lines and branches of code



void funcPiece1()

    // also many lines and branches of code


void funcCore()

    funcInitThis();
    funcInitThat();

#pragma omp parallel
    
#pragma omp sections
        
#pragma omp section
            
                funcPiece0();
            //omp section
#pragma omp section
            
                funcPiece1();
            //omp section
        //omp sections
    //omp parallel



int main()


    funcInitThis();
    funcInitThat();
#pragma omp parallel
    
    while(1)
    
        funcCore();
    
    


我想要做的是避免每次迭代的创建/销毁,并在程序的开始/结束时进行一次。我对“并行”子句的置换尝试了许多变化。我基本上具有相同的本质如下:(每个程序运行只有一个线程创建/销毁) --我尝试过,但在初始化函数中“非法访问”失败。

void funcPiece0()

    // many lines and branches of code



void funcPiece1()

    // also many lines and branches of code


void funcCore()

    funcInitThis();
    funcInitThat();

//#pragma omp parallel
//  
#pragma omp sections
        
#pragma omp section
            
                funcPiece0();
            //omp section
#pragma omp section
            
                funcPiece1();
            //omp section
        //omp sections
//  //omp parallel



int main()


    funcInitThis();
    funcInitThat();

    while(1)
    
        funcCore();
    


--

任何帮助将不胜感激! 谢谢!

【问题讨论】:

请注意,OpenMP 网站有一个论坛,您可以在其中发布有关 OpenMP 的问题——请访问openmp.org/forum 【参考方案1】:

OpenMP 仅在启动时创建工作线程。并行编译指示不会产生线程。你如何确定线程是产生的?

【讨论】:

感谢您的回答。我的程序挂了,当我用调试器暂停它时,使用我的编译器,我看到许多工作线程正在执行“pragma omp parallel”所在的函数。 “应该”在哪里产生线程? 线程在程序启动时启动(或第一次需要,取决于实现)。在其他任何地方暂停你的程序,你会发现线程仍然存在 虽然我测试的地方似乎是这样(std::this_thread::get_id()omp_get_thread_num() 都显示重复执行并行区域的重复值),但这与官方文档相矛盾,其中它说@ 987654324@ 构造“创建线程”。 openmp.org/spec-html/5.0/openmpse14.html【参考方案2】:

这是可以做到的!这里的关键是将循环移动到一个单独的并行部分中,并确保无论用于确定是否重复,所有线程都会做出完全相同的决定。我在检查循环条件之前使用了共享变量并进行了同步。

所以这段代码:

initialize();
while (some_condition) 
  #pragma omp parallel
  
     some_parallel_work();
  

可以转换成这样的:

#pragma omp parallel

  #pragma omp single
  
    initialize();  //if initialization cannot be parallelized
  
  while (some_condition_using_shared_variable) 
    some_parallel_work();
    update_some_condition_using_shared_variable();
    #pragma omp flush
  

最重要的是确保每个线程在代码中的相同点做出相同的决定。

作为最后的想法,基本上人们正在做的是将创建/销毁线程的开销(每次#pragma omp parallel 的一部分开始/结束)转换为线程决策的同步开销。我认为同步应该更快,但是这里有很多参数在起作用,这可能并不总是如此。

【讨论】:

以上是关于如何让 OpenMP 在程序每次运行时只创建一次线程?的主要内容,如果未能解决你的问题,请参考以下文章

如何确保 MainActivity 只创建一次

使用 Flask + SqlAlchemy 只创建一张表

在 Cloud Firestore 中如何制作一个,只创建一次安全规则

如何使用 SQLAlchemy 只创建一张表?

如何在一个包含多个 matplotlib 直方图的图中设置 x 轴的边界并只创建一列图?

Sprite Kit:为所有场景只创建一次节点