我有4个线程,我想一次启动3个功能。每个函数都需要一个线程 但是这段代码每次启动4次
#pragma omp parallel
{
Func1();
Func2();
Func3();
}
我有这个结果:
Func * 1 *已启动
Func * 1 *已启动
Func * 1 *已启动
Func * 1 *已启动
Func * 1 *已完成
Func * 1 *已完成
Func * 1 *已完成
Func * 1 *已完成
Func * 2 *已启动
Func * 2 *已启动
Func * 2 *已启动
Func * 2 *已启动
Func * 2 *已完成
Func * 2 *已完成
Func * 2 *已完成
Func * 2 *已完成
...
我应该如何更改代码以显示如下:
Func * 1 *已启动
Func * 2 *已启动
Func * 3 *已启动
Func * 2 *已完成
Func * 1 *已完成
Func * 3 *已完成
答案 0 :(得分:5)
您要搜索的是sections
工作共享结构。语法应如下:
#pragma omp parallel
{
#pragma omp sections
{
#pragma omp section
Func1();
#pragma omp section
Func2();
#pragma omp section
Func3();
}
}
我建议您参考specifications及其中的示例,了解有关此构造如何工作的更多信息。
答案 1 :(得分:1)
正如Massimiliano已经回答的那样,实现目标的最简单方法是使用sections
构造:
#pragma omp parallel sections
{
#pragma omp section
Func1();
#pragma omp section
Func2();
#pragma omp section
Func3();
}
(当sections
构造是嵌套在parallel
区域内的唯一构造时,两个编译指示可以如图所示组合)
每个section
范围都紧跟在它之后的语句或块。例如。如果你想在一个部分中包含更多代码,你应该把它放在一个块中:
#pragma omp section
{
Func1();
SomeOtherFunc1();
}
控制每个线程执行操作的更一般方法是检查omp_get_thread_num()
返回的线程ID并按照分支进行分支。这类似于MPI程序的编写方式:
#pragma omp parallel
{
switch (omp_get_thread_num())
{
case 0:
Func1();
break;
case 1:
Func2();
break;
case 2:
Func3();
break;
default:
// Do nothing
}
}
一个明显的缺点是,除非团队中至少有3个线程执行并行区域,否则它只能工作,即依赖于线程ID的代码变得有些不可移植。相反,sections
指令适用于任意数量的线程,例如如果只有一个线程,则所有部分都将按顺序执行。