【问题标题】:OpenMP code executed in thread poolOpenMP 代码在线程池中执行
【发布时间】:2011-06-17 07:08:11
【问题描述】:

我正在考虑一种设计,即线程池将执行代码块,其中可能包含 OpenMP 语句(大多数情况下是并行的)。 (类似于:How to deal with OpenMP thread pool contention 我猜)。 我的问题是,如果 OpenMP 并行区域每次都由不同的线程执行,是否会导致问题或导致性能下降。

编辑:

目标将是 Linux (gcc) 和 Windows (msvc)。

当我的第一个原型完成后,我将对其进行基准测试(这将受到我在这里得到的答案的影响)。

这是一个简单的例子:

class Task
{
public:
    void doTask()
    {
        #pragma omp parallel
        {
            // do work in parallel
        }
    }
};

现在假设您创建了一个Task 的实例,并将其提供给线程池(thread-0,...,thread-n)。一个线程执行doTask()。稍后,您再次将相同的 Task 对象放入线程池,然后再次...。 所以doTask()(和并行部分)将由不同的线程执行。我想知道 OpenMP 是否有效地处理了这件事(例如,不是每次都重新创建该部分的线程)。

【问题讨论】:

  • 根据我优化代码的经验,有一个方法可以知道某件事是否会提高性能:对其进行基准测试。仅当实现过于复杂时,思考和创建假设是否缓慢才有用。创建一个真实的测试演示并对其进行基准测试。

标签: c++ multithreading threadpool openmp


【解决方案1】:

Vitor 的评论是正确的。很难判断这是否会导致问题,因为答案取决于许多因素(即数据布局、访问数据的方式、缓存大小、运行的处理器类型以及列表继续)。

我能说的是,你可能会也可能不会让这个工作。 OpenMP 规范 - 以及大多数其他线程模型 - 没有说明模型如何或是否会“很好地协同工作”。例如,即使某些 OpenMP 实现将 pthreads 用于底层实现,除非该实现已经完成了一些工作,否则用户无法直接调用 pthreads 库并使其与 OpenMP 一起工作。这方面的当前示例是 gcc 错误 42616(pthread 内的 OMP 循环导致崩溃)。另一个例子是英特尔,它的编译器支持许多并行模型,但努力让它们一起工作。由于你没有说你将使用什么编译器,我只能说在你承诺做一些大的事情之前尝试一个小的示例代码来看看它是否有效。

我过去曾尝试过这样的事情。我使用了 pthread,然后使用了 OpenMP 构造。我发现对于我的应用程序来说它工作得很好。当遇到 OpenMP 并行区域时,每个 pthread 都被视为初始线程。然后,OpenMP 运行时为该区域创建附加线程并运行该区域。由于大多数 OpenMP 实现不会破坏线程,而是将它们放在空闲池中以便在遇到另一个区域时重用,因此开销似乎很好 - 但后来我在该区域有很多工作要做。所以它可以工作 - 但你必须小心。

【讨论】:

  • 谢谢。综上所述,如果您想非常安全,OpenMP 结构应该只在主线程中执行。但是从错误报告中我认为它应该可以工作并且没有什么被禁止的(至少对于 gcc 来说不是)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-12-01
  • 2022-01-03
  • 1970-01-01
  • 2012-09-04
  • 2018-12-11
  • 2014-08-27
相关资源
最近更新 更多