C 如何要求OpenMP在程序每次运行时仅创建一次线程?

C 如何要求OpenMP在程序每次运行时仅创建一次线程?,c,multithreading,openmp,C,Multithreading,Openmp,我正在尝试并行化一个由第三方编写的大型程序。我不能透露代码,但我会尝试给出我想做的最接近的例子。 基于下面的代码。如您所见,由于子句“parallel”在while循环中,线程的创建/销毁在每次迭代中完成,这是非常昂贵的。 鉴于我无法将初始值设定项…等移到“while”循环之外 --基本代码 void funcPiece0() { // many lines and branches of code } void funcPiece1() { // also many lin

我正在尝试并行化一个由第三方编写的大型程序。我不能透露代码,但我会尝试给出我想做的最接近的例子。 基于下面的代码。如您所见,由于子句“parallel”在while循环中,线程的创建/销毁在每次迭代中完成,这是非常昂贵的。 鉴于我无法将初始值设定项…等移到“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仅在开始时创建工作线程。并行杂注不会生成线程。如何确定线程是否已生成?

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

所以这个代码:

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的一部分开始/结束时)转换为线程决策的同步开销。我认为同步应该更快,但是这里有许多参数在起作用,这可能并不总是如此。

感谢您的回答。我的程序挂起了,当我使用编译器使用调试器暂停它时,我看到许多工作线程在执行“pragma omp parallel”所在的函数。线程“应该”在哪里生成?线程在程序启动时启动(或者需要第一次启动,具体取决于实现)。将您的程序暂停到其他任何地方,您会注意到线程仍在那里,而我测试的地方似乎也是如此(这两个都是
std::this\u thread::get\u id()
omp\u get\u thread\u num()
显示重复执行并行区域的重复值),这与官方文档相矛盾,其中表示
并行
构造“创建线程”。请注意,OpenMP网站有一个论坛,您可以在其中发布有关OpenMP的问题——请访问