2011-01-28 24 views
2

我正在考虑一个线程池将执行代码块的设计,它可能包含OpenMP语句(主要是并行)。 (类似于:How to deal with OpenMP thread pool contention我猜)。 我的问题是,如果OpenMP并行区域每次都由不同的线程执行,它会导致问题或导致性能不佳。在线程池中执行的OpenMP代码

编辑:

目标将是Linux操作系统(GCC)和Windows(MSVC)。

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

下面是一个简单的例子:

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

现在想象你创建的Task一个实例给它一个线程池(线程0,...,螺纹-N)。一个线程执行doTask()。之后,您再次将相同的Task对象放入线程池,并再次......。 所以doTask()(和平行部分)将由不同的线程执行。我想知道这是否由OpenMP有效地处理(例如,该部分的线程不会每次都重新创建)。

+0

关于什么编译器? – 2011-01-28 15:58:20

+2

根据我的经验优化代码,有一种方法可以知道某件事是否会提高性能:进行基准测试。如果实施过于复杂,思考和创建假设只有在某些事情很慢时才有用。创建一个真实的测试演示并进行基准测试 – 2011-01-28 16:36:33

回答

4

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

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

我曾尝试过这样的事情。我使用了pthreads,然后使用OpenMP构造。我发现,对于我的应用程序,它工作正常。当遇到OpenMP并行区域时,每个pthread被认为是一个初始线程。然后,OpenMP运行时为该区域创建其他线程并运行该区域。由于大多数OpenMP实现不会销毁线程,但是在遇到另一个区域时将它们放在空闲池中以供重用时,开销似乎很好 - 但之后我在该地区做了大量工作。所以它可以工作 - 但你必须小心。