C语言 我如何要求OpenMP在每次运行程序时只创建一次线程?



我正在尝试并行化一个由第三方编写的大型程序。我不能透露代码,但我会尽量给出我想要做的最接近的例子。基于下面的代码。正如您所看到的,由于子句"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();
    }
    }
}

我所要做的是避免每次迭代的创建/销毁操作,并在程序的开始/结束时执行一次。我尝试了许多替代"parallel"从句的变体。我基本上有相同的本质如下:(每个程序运行只有一个线程创建/销毁)——我尝试过,但在初始化函数中"非法访问"失败。

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

最新更新