我想使用OpenMP
来达到这个效果:修复线程数,如果有空闲线程,则将任务分配给它,否则等待空闲线程。以下是我的测试代码:
#include <omp.h>
#include <stdio.h>
#include <unistd.h>
void func(void) {
#pragma omp parallel for
for (int i = 0; i < 3; i++)
{
sleep(30);
printf("%d\n", omp_get_thread_num());
}
}
int main(void) {
omp_set_nested(1);
omp_set_num_threads(omp_get_num_procs());
#pragma omp parallel for
for (int i = 0; i < 8; i++)
{
printf("%d\n", omp_get_thread_num());
func();
}
return 0;
}
实际上,我的机器包含24
核心,所以
omp_set_num_threads(omp_get_num_procs())
将在开头启动24
个帖子。然后main
的{{1}}将占用for-loop
个帖子,在每个帖子中,将调用8
,因此应该使用额外的func
个帖子。根据我的计算,我认为2
线程就足够了。但在实际运行中,生成了24
个线程。
所以我的问题如下:
(1)为什么208
似乎已经创建了这么多线程呢?
(2)是否可以修复线程数(例如,与核心数相同)并在有闲置时分派任务?
答案 0 :(得分:1)
1)这就是parallel for
被定义为parallel
指令的方式,紧接着是loop
指令。因此,基于工作共享粒度的线程创建没有限制。
编辑:澄清OpenMP将:
所以在你的情况下,8个线程遇到内部并行构造,每个构造产生24个新线程,并且外部循环的16个线程不会。所以你总共有8 * 24 + 16 = 208个主题。
2)是的,顺便说一句,这个概念在OpenMP中被称为task
。 Here is a good introduction
答案 1 :(得分:0)
在OpenMP中,一旦您询问了特定数量的线程,运行时系统就会将它们提供给您的并行区域(如果能够这样做),并且这些线程在并行区域处于活动状态时不能用于其他工作。运行时系统无法猜测您不会使用您请求的线程。
因此,如果您需要较少的线程,或者使用其他可以动态管理活动线程数的并行化技术,您可以做的是要求较少数量的线程。例如,如果要求8个线程用于外部并行线程,3个线程用于内部区域,则使用OpenMP,您可以使用24个线程(如果线程可以重复使用,则更少,例如,当并行区域不同时运行时)。
- 安德烈
答案 2 :(得分:0)
你应该试试
#pragma omp task
此外,在我看来,避免使用嵌套的omp线程。