我想运行以下代码(如下).我想生成两个独立的线程,每个线程都会运行并行for循环.不幸的是,我收到了一个错误.显然,并行for不能在里面产生section.怎么解决?
#include <omp.h>
#include "stdio.h"
int main()
{
omp_set_num_threads(10);
#pragma omp parallel
#pragma omp sections
{
#pragma omp section
#pragma omp for
for(int i=0; i<5; i++) {
printf("x %d\n", i);
}
#pragma omp section
#pragma omp for
for(int i=0; i<5; i++) {
printf(". %d\n", i);
}
} // end parallel and end sections
}
Run Code Online (Sandbox Code Playgroud)
而错误:
main.cpp: In function ‘int main()’:
main.cpp:14:9: warning: work-sharing region may not be closely nested inside of work-sharing, critical, ordered, master or explicit task region [enabled by default]
main.cpp:20:9: warning: work-sharing region may not be closely nested inside of work-sharing, critical, ordered, master or explicit task region [enabled by default]
Run Code Online (Sandbox Code Playgroud)
在这里,您必须使用嵌套并行性.与这个问题omp for的sections是,在范围内的所有线程都参加了omp for,而且他们显然不-它们是由部分破碎.所以你必须引入函数,并在函数内做嵌套的并行.
#include <stdio.h>
#include <omp.h>
void doTask1(const int gtid) {
omp_set_num_threads(5);
#pragma omp parallel
{
int tid = omp_get_thread_num();
#pragma omp for
for(int i=0; i<5; i++) {
printf("x %d %d %d\n", i, tid, gtid);
}
}
}
void doTask2(const int gtid) {
omp_set_num_threads(5);
#pragma omp parallel
{
int tid = omp_get_thread_num();
#pragma omp for
for(int i=0; i<5; i++) {
printf(". %d %d %d\n", i, tid, gtid);
}
}
}
int main()
{
omp_set_num_threads(2);
omp_set_nested(1);
#pragma omp parallel
{
int gtid = omp_get_thread_num();
#pragma omp sections
{
#pragma omp section
doTask1(gtid);
#pragma omp section
doTask2(gtid);
} // end parallel and end sections
}
}
Run Code Online (Sandbox Code Playgroud)
OpenMP 无法在并行区域内创建并行区域。这是因为 OpenMP 在程序开始时创建了 num_threads 个并行线程,在非并行区域中其他线程不被使用并处于休眠状态。他们这样做是因为与唤醒睡眠线程相比,频繁生成新线程相当慢。
因此,您应该仅并行化循环:
#include <omp.h>
#include "stdio.h"
int main()
{
omp_set_num_threads(10);
#pragma omp parallel for
for(int i=0; i<5; i++) {
printf("x %d\n", i);
}
#pragma omp parallel for
for(int i=0; i<5; i++) {
printf(". %d\n", i);
}
}
Run Code Online (Sandbox Code Playgroud)