【问题标题】:How to nest omp for in omp single using OpenMP如何使用 OpenMP 在 omp single 中嵌套 omp
【发布时间】:2011-08-19 11:50:17
【问题描述】:

我有一个我不想并行化的 for 循环,它调用一个我想并行化的函数(其中有一个我想并行化的 for 循环)。我想将并行区域放在整个区域之外,以便我的线程只创建一次(以减少线程创建的开销)。

但是,目前我有一个 omp single 覆盖 for 循环,它调用函数和函数内部的 omp for 来处理内部 for 循环。它手,根据OMP single hangs inside for,这是因为这样做是非法的!

如果我不能那样做,我该怎么做?我想确保只有一个线程运行外部 for 循环并调用函数,但在函数内部我可以获得完全的并行性。

这可能吗?有什么想法吗?

【问题讨论】:

  • 你知道线程创建开销真的是个问题吗?良好的 OpenMP 实现可能会为您关心这一点,当没有并行区域处于活动状态时,保持一些线程在内部停放。
  • 我不确定我正在使用什么 OpenMP 实现(如果有帮助,我正在使用 GCC 4.3.3),但我不确定它是否这样做。当我在函数内部有一个被多次调用的并行区域时,我似乎得到了显着的减速(而不是加速),所以这表明我的实现可能没有这样做。
  • 您可以很容易地检查这一点,方法是要求每个线程在并行区域的开头打印其pthread_self() 值,并检查线程是否被重用或重新创建。
  • @Alexey - 谢谢。我已经尝试过了,似乎线程正在被重新使用。我现在只是有点困惑为什么我的代码实际上运行速度较慢......但我猜这是一个不同的问题!

标签: c openmp parallel-processing


【解决方案1】:

大多数实现只创建一次线程 - 在程序启动时或遇到第一个并行区域时。一旦创建,它们通常不会被销毁,而是在遇到并行区域结束时放入空闲线程池(由 OpenMP 实现处理)。这意味着您应该能够将并行区域放在循环中,并且每次遇到并行区域时都不会产生线程创建开销。每次遇到并行区域时都会有一些小的开销,但比创建线程时要小得多。

【讨论】:

  • 这很有趣。在我的并行编程课程中,我们被警告不要继续拥有新的并行区域,因为这在开销时间上非常昂贵。我试过只在内部函数中使用#pragma omp parallel for,但与串行运行相比,这种方式的代码运行速度要慢得多(有4个线程)。关于如何实现这一目标的任何其他想法?
  • 一般来说我会同意你所教的。不幸的是,OpenMP 模型有限制。您可以使用嵌套并行性来做到这一点,但这会更糟。如果内部循环中的工作独立于先前的迭代,那么您也许可以使用任务。除此之外,没有看到更多你想要做的事情,我没有想法。
  • @robintw,你可以做一些实验来看看是什么导致了减速。例如,尝试将并行区域的线程数设置为 1。这样,OpenMP 的开销应该相当小,程序应该比串行慢一点。如果它慢得多,那么原因可能与并行性的开销不同。
【解决方案2】:

怎么样: - 将您的内部循环放入#pragma omp parallel - 在外循环之前将活动线程数设置为 1 - 在调用其他函数之前将其设置回 N - 在函数内部放置一个#pragma omp

?

并行部分在 OMP 中的函数边界上是瞬态的,设置活动线程的数量不应太有害。但不需要进行测试/基准测试。

【讨论】:

  • 在区域启动后更改执行并行区域的线程数是不可能的。来自规范:“创建团队后,团队中的线程数在该并行区域的持续时间内保持不变。”
  • 这就是我发送后担心的问题。感谢 Alexey 的提醒
  • 感谢@Alexey - 这可能是我尝试实现它时不起作用的原因!
猜你喜欢
  • 2013-09-20
  • 1970-01-01
  • 2021-12-03
  • 2021-09-07
  • 2018-07-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多