在线程池中执行的OpenMP代码

时间:2011-01-28 14:41:46

标签: c++ multithreading threadpool openmp

我正在考虑设计一个线程池将执行代码块,其中可能包含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有效处理(例如,每次都不重新创建该节的线程)。

1 个答案:

答案 0 :(得分:4)

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

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

过去我曾经尝试过类似的东西。我使用了后来使用OpenMP结构的pthreads。我发现,对于我的应用程序,它工作正常。遇到OpenMP并行区域时,每个pthread都被视为初始线程。然后,OpenMP运行时为该区域创建了其他线程并运行该区域。由于大多数OpenMP实现不会破坏线程,而是将它们放在空闲池中以便在遇到另一个区域时重用,开销似乎很好 - 但后来我在该区域做了很多工作。所以它可以工作 - 但你必须要小心。