【发布时间】:2013-03-04 17:47:41
【问题描述】:
我有一个使用 OpenMP 并行化的外部 for 循环。然而,在这个 for 循环中,有一些代码也可以并行执行。
我可以使用 OpenMP 的sections 子句来并行化吗?这甚至可能吗?由于 for 循环的每次迭代仅由一个线程运行,我可以(在每次迭代中)要求某些代码部分由多个线程并行运行吗?其余代码应仅由一个线程运行,即该循环迭代已分配到的线程。
例如。我有以下代码:
omp_p = omp_get_max_threads();
omp_set_nested(1);
#pragma omp parallel for num_threads(omp_p/2)
for(int p=0;p<omp_p/2;p++){
size_t a = (p*N)/(omp_p/2);
size_t b = ((p+1)*N)/(omp_p/2);
for(int i=a;i<b;i++){
/*Work on A[a]->A[b]*/
for(int j=0;j<n;j++){
for(int k=0;k<N;k++){
/*Serial code*/
#pragma omp parallel sections
{
#pragma omp section
{
}
#pragma omp section
{
}
}
/*Serial work*/
#pragma omp parallel sections
{
#pragma omp section
{
}
#pragma omp section
{
}
}
/*Serial code*/
}
}
}
}
这会导致程序运行得比我根本不使用并行部分要慢得多..
【问题讨论】:
-
除了嵌套并行的巨大开销之外,您的
i、j和k循环计数器获得shared的默认共享类,并且应该显式声明private。跨度> -
哦,对不起,我忘了在 for() 大括号中将它们声明为整数。更正了这个..
-
是什么阻止您简单地分解所有线程之间的循环并串行执行内部循环中的所有内容?与线程数相比,
N是否太低? -
这就是我编写它的方式,但我意识到除了一些分配(需要串行完成)之外,最里面的“k”循环主要有两个可以并行执行的大部分。它类似于矩阵乘法代码,矩阵在线程之间划分,大部分工作发生在最内层循环中。所以我想知道是否应该为每个线程提供更大的矩阵块并保留两个线程(每个线程)以并行执行最内层循环中的操作。 N ~ 5*omp_p
-
OpenMP 与大多数其他并行编程范式一样,引入了同步开销,因此它支持计算模型,其中每个线程尽可能多地工作并尽可能少地同步。您的实现未充分利用线程,因为在嵌套并行之外存在串行部分,其中第二个线程什么都不做。移除嵌套的并行性,让外循环使用所有线程,然后针对错误共享等情况分析代码。
标签: openmp