c – OpenMP:嵌套并行化有什么好处?

根据我的理解,#pragma omp parallel及其变体基本上在许多并发线程中执行以下块,这对应于CPU的数量.当嵌套并行化时 – 并行为并行,并行函数内的并行函数等 – 内部并行化会发生什么?

我是OpenMP的新手,我想到的情况可能相当简单 – 将矢量与矩阵相乘.这是在两个嵌套的for循环中完成的.假设CPU的数量小于向量中的元素数量,那么尝试并行运行内部循环是否有任何好处?线程总数是否会大于CPU数量,还是内部循环会顺序执行?

解决方法:

(1)OpenMP中的嵌套并行性:
http://docs.oracle.com/cd/E19205-01/819-5270/aewbc/index.html

您需要通过设置OMP_NESTED或omp_set_nested来打开嵌套并行性,因为默认情况下许多实现都会关闭此功能,即使某些实现也不完全支持嵌套并行性.如果启用,则无论何时满足并行,OpenMP都将创建OMP_NUM_THREADS中定义的线程数.因此,如果是2级并行,则线程总数将为N ^ 2,其中N = OMP_NUM_THREADS.

这种嵌套并行性将导致超额预订(即,繁忙线程的数量大于核心),这可能降低加速.在极端情况下,嵌套并行性被递归调用,线程可能膨胀(例如,创建1000个线程),并且计算机只是浪费时间进行上下文切换.在这种情况下,您可以通过设置omp_set_dynamic来动态控制线程数.

(2)矩阵向量乘法的一个例子:代码看起来像:

// Input:  A(N by M), B(M by 1)
// Output: C(N by 1)
for (int i = 0; i < N; ++i)
  for (int j = 0; j < M; ++j)
     C[i] += A[i][j] * B[j];

通常,在外环可能的情况下并行化内环是不好的,因为分叉/连接线程的开销. (尽管许多OpenMP实现预先创建了线程,但它仍然需要一些将任务分派给线程并在并行结束时调用隐式屏障)

你担心的是N< CPU数量.是的,对,在这​​种情况下,加速将受到N的限制,并且让嵌套并行性肯定会带来好处. 但是,如果N足够大,则代码会导致超额订阅.我只想到以下解决方案:
>更改循环结构,以便只存在1级循环. (看起来很可行)
>专业化代码:如果N很小,那么执行嵌套并行,否则不要这样做.
>使用omp_set_dynamic嵌套并行.但是,请确保omp_set_dynamic如何控制线程数和线程活动.实施可能会有所不同.

上一篇:PHP:带有递归函数的嵌套菜单,只展开一些节点(不是所有树)


下一篇:sql – 如何递归查找子项的所有ID?