如何让 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 在程序每次运行时只创建一次线程?的主要内容,如果未能解决你的问题,请参考以下文章
在 Cloud Firestore 中如何制作一个,只创建一次安全规则