我想运行以下代码(如下)。我想生成两个独立的线程,每个线程都会运行并行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
}
错误:
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]
答案 0 :(得分:6)
这里你必须使用嵌套并行。 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
}
}
答案 1 :(得分:3)
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);
}
}
答案 2 :(得分:1)
实际上,最佳线程数等于可用CPU核心数。因此,每个并行应该在所有可用内核中处理,这在 omp部分中是不可能的。所以,你想要实现的目标并不是最优的。 tune2fs&#39;建议执行没有部分的两个循环是有意义的,并提供最佳的性能。你可以在另一个函数内部执行并行循环,但是这个&#34;作弊&#34;没有提高性能。