使用OpenMP进行复杂线程处理

4

我的老板要求我从boost::thread改为OpenMP。

问题很简单:每5次迭代(int it = 5,10,15...)将模拟结果写入磁盘。为了简单起见,假设我有一颗8核CPU。我创建了9个线程;线程0用于IO,其他8个用于计算。当(it%5 == 0)时,我检查线程0是否已经完成。如果是,我创建另一个线程,调用0,并要求它将结果写入磁盘。如果没有,所有线程都必须等待。通常,写出结果所需的时间少于5次迭代,因此我有效地“隐藏”了IO成本。

我花了几个小时研究OpenMP,我想可以使用“task”结构来完成同样的算法,但我不知道如何同步线程。请OpenMP专家帮忙解答,谢谢。

当前的伪代码如下

boost::thread pool[9];
for(int it=0;it<1000;it++)
{
    - simulate using pool[1,8]
    - if(it%5 == 0)
         + check pool[0]
         + if finished: create new thread, assign to pool[0], write data out
         + if not, wait
}

1
我喜欢“老板这样说”的思路,让老板了解OpenMP并非线程,你可以查看Intel TBB。 - whatnick
2
@whatnick:虽然它有一个线程类,但Intel TBB并不仅仅是关于线程的。 - Alexey Kukanov
OpenMP有"锁"(类似于互斥锁),我认为可以使用它来跟踪线程。在这种情况下,我认为解决方案是让IO任务解锁该锁,并确保在生成另一个IO任务之前解锁该锁。当我提出这个问题时,我不知道有"锁"。我认为我已经找到了自己的答案,但我仍然需要OpenMP专家来验证。 - JohnC
2个回答

2
英译中:
Intel对于OpenMP与Threads的困境有一个非常好的答案,我建议您听从他们的意见并要求您的老板接受一些教育。
OpenMP非常面向循环,您可以并行化整个循环而不是使用同步线程。

教育老板是不可能的事情。同样,Boost也很好,但老板不想将该库与我们的软件捆绑在一起。OpenMP 3有一个新的“任务”结构,可以随意生成线程,因此必须有某种方式来知道线程何时完成... - JohnC
英特尔库...我不太喜欢。等到你不得不阅读Rusnglish手册时(我指的是MKL库),你就会明白我的意思了。我的公司坚持使用gcc,我认为老板是对的... - JohnC

0

整体上,您的设计看起来是正确的:为I/O拥有一个单独的线程和一个线程池来进行计算是正确的。在计算部分中,您可能可以使用OpenMP替换池[1..8]中的Boost线程,但我不会超出那个范围。如果您无法使用Boost,请使用POSIX线程。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接