编辑:
目标将是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有效处理(例如,每次都不重新创建该节的线程)。
答案 0 :(得分:4)
维托尔的评论是正确的。很难判断这是否会导致问题,因为答案取决于许多因素(即数据布局,访问数据的方式,缓存大小,运行的处理器类型以及列表继续)。
我能说的是,你可能会或可能不会让这个工作。 OpenMP规范 - 以及大多数其他线程模型 - 没有说明模型将如何或“一起玩得很好”。例如,即使某些OpenMP实现将pthread用于底层实现,除非实现已完成某些工作,否则用户无法直接调用pthreads库并使其与OpenMP一起工作。目前的一个例子是gcc bug 42616(pthread中的OMP'ed循环导致崩溃)。另一个例子是英特尔,其编译器支持许多并行模型,但他们努力让它们一起工作。既然你还没有说过要使用什么编译器,我只能尝试一个小的示例代码,看看它是否在你承诺做大事之前是否有效。
过去我曾经尝试过类似的东西。我使用了后来使用OpenMP结构的pthreads。我发现,对于我的应用程序,它工作正常。遇到OpenMP并行区域时,每个pthread都被视为初始线程。然后,OpenMP运行时为该区域创建了其他线程并运行该区域。由于大多数OpenMP实现不会破坏线程,而是将它们放在空闲池中以便在遇到另一个区域时重用,开销似乎很好 - 但后来我在该区域做了很多工作。所以它可以工作 - 但你必须要小心。