OpenMP,用于循环内部部分

我想运行以下代码(如下)。 我想生成两个独立的线程,每个线程都会运行并行for循环。 不幸的是,我收到了一个错误。 显然,并行不能在section内部产生。 怎么解决?

 #include  #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] 

OpenMP无法在并行区域内创建并行区域。 这是因为OpenMP在程序开始时创建num_threads并行线程,在非并行区域中其他未使用和hibernate。 他们这样做了,因为与醒来的睡眠线程相比,频繁生成新线程的速度相当慢。

因此,您应该只对循环进行并行化:

 #include  #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); } } 

在这里,您必须使用嵌套并行性。 这些sections omp for的问题在于,范围内的所有线程都必须参与omp for ,而且它们显然不会 – 它们被部分分解。 所以你必须引入函数,并在函数内做嵌套的并行。

 #include  #include  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 } } 

实际上,最佳线程数等于可用CPU核心数。 因此,每个并行应该在所有可用内核中处理,这在omp部分内是不可能的。 所以,你想要实现的目标并不是最优的。 tune2fs’建议执行两个没有部分的循环是有意义的,并提供最佳的性能。 你可以在另一个函数内部执行并行循环,但这种“欺骗”不会提高性能。