科学计算:OpenMP还是Pthreads

4
我正在开发科学计算社区的代码,特别是用于迭代解决线性方程组(Ax=b形式)。我已经使用了BLAS和LAPACK进行原始矩阵子程序,但我现在意识到有一些手动并行化的空间。我正在使用共享内存系统,留下了两个选择:OpenMP和PThreads。
假设时间不是最重要的因素(&代码的性能是),哪种并行化方式更好、更具未来性,并且可能可移植(到CUDA)?使用PThreads所花费的时间是否值得性能提升?
我相信我的应用程序(基本上涉及同时启动许多事物,然后从所有这些事物中操作“最佳”值),将受益于明确的线程控制,但我担心编码将花费太多时间,最终不会有性能回报。
我已经看过这里的几个类似问题,但它们都与一般应用程序有关。 这个是关于Linux中通用多线程应用程序的问题。 这个也是一个一般性的问题。

我知道SciComp.SE,但觉得在这里更相关。


基本上是同时启动许多事情,然后从所有事情中操作“最佳”值。我相信CPlex具有类似于您的算法。我不知道他们选择了什么底层并行化工具,但也许您可以找出来(这并不一定意味着他们的选择对您来说是最好的,但了解总是好的)。 - François Févotte
boost threads为C++提供了与pthreads(或其他线程库)非常好的接口,我认为它完全值得一试。但是出于编程便捷性考虑,我最终选择了OpenMP。此外,还可以考虑使用Intel IPP/TBB。 - Anycorn
如果你正在使用BLAS或LAPACK,为什么不直接使用Eigen呢?它内置了对SIMD(SSE)和OpenMP的支持。 - Z boson
3个回答

7
您的问题似乎认为使用OpenMP编程的效率比使用Pthreads更高,而使用Pthreads执行效率更高。总体而言我认为您是正确的。然而,一段时间以来,我决定我的时间比我的计算机的时间更重要,选择了OpenMP。这不是一个我有理由后悔的决定,也不是一个我有任何硬证据证明的决定。
但是,您认为选择只局限于OpenMP和Pthreads是错误的,MPI(我假设您至少听说过,如果没有,请再次发布)也可以在共享内存机器上运行。对于某些应用程序,MPI可以编程实现优于OpenMP在共享内存计算机上的性能而不需要太多困难。
三年前,科学开发人员工具箱中必不可少的并行化工具是OpenMP和MPI。使用这些工具的任何人都是一个庞大的社区的成员,比使用Pthreads和MPI的用户社区要大得多(仅凭个人经验)。如今,GPU和其他加速器频繁涌现,情况更加分散,并且很难从HMPP、ACC、Chapel、MPI-3、OpenMP4、CUDA、OpenCL等中选择一个胜者。我仍然认为OpenMP + MPI是一个有用的组合,但不能忽视新生代。
顺便说一下,我致力于开发地球物理应用的计算EM代码,因此是相当“硬核”的“科学计算”。

我曾尝试在共享内存上运行ScaLapack而不是BLAS,但是即使是Hello World也很困难,这让人望而却步。如果我没记错的话,CUDA是基于pthread“模型”的?虽然我在CUDA方面没有太多经验,但是CuBlas的代码编写方式似乎与pthread相似。如果我确定我的应用程序很快会被移植到GPU上,那么你会推荐什么呢?那时所有其他因素都将变得不那么重要。 - user1132648
我没有足够的GPU计算经验来提供好的建议。 - High Performance Mark
1
我不确定这里是否有人正在将GPU计算和一般并行计算的身份混淆,这可能让@rubenvp感到惊讶。我确实看到人们使用GPU来解决科学/工程中的数值计算问题。SO上充斥着关于这个主题的问题。 - High Performance Mark
1
@rubenvb,你是在暗示科学界不使用GPU/CUDA吗?我的意思是,当涉及到Tesla/Fermi时,虽然可能不是使用最多的人,但我们可能比任何其他人都要订购更多。 - user1132648
+1 - 我总是喜欢High Performance Marks的帖子。这篇也不例外。 - duffymo
显示剩余3条评论

2
我意识到我的回答很长,所以我先放出结论给那些急于求成的人:
简短的回答:我认为openMP和pthreads基本上是一样的,你应该选择哪个需要更少的开发时间(如果它符合你的需求,可能是openMP)。但是如果你想要投入开发时间,也许你应该重新设计你的代码,使其能够适应其他范例(例如向量化以利用SSE / AVX或GPU)。
开发方面:
如果你开发线性求解器,我假设你的代码将是(非常)长寿的(即它可能会超过使用它的物理模型的寿命)。在这种情况下,尤其是如果你没有一个大型开发团队,我认为你应该首先基于开发时间、可维护性和……
此外,你不应该假设今天的“最佳”选择(无论“最佳”是什么)明天可能仍然是“最佳”的选择。因此,即使你现在面临一个openMP vs pthreads的问题(甚至现在,如@HighPerformanceMark的答案中所述,谱系已经比这更广泛了),你应该期望在未来有更多的选择。
如果你现在有开发时间可以花费,我认为最好的投资方式是将你的代码中所有计算密集型内核抽象出来,以便你可以轻松地将它们适应不同的并行化范例。在这方面,最重要(也是最困难)的事情是处理数据结构:为了受益于GPGPU计算的协同作用,需要将数据按不同于传统缓存优化方式的顺序排列。
这就引出了结论:所有基于线程的解决方案本质上是等效的(无论是在性能还是代码架构上),你应该选择哪个解决方案需要最少的开发时间。但是如果你想要投入开发时间,也许你应该重新设计你的代码,使其可以被并行化或向量化(从而利用SSE / AVX或GPU)。如果你成功做到了这一点,你将能够跟随硬件/软件的演变并保持性能。

"..: 所有基于线程的解决方案在性能和代码架构方面本质上是相同的,您应该选择需要最少开发时间的解决方案。" 如果我假设这是真的,那么不是OpenMP是默认的赢家,因为在OpenMP中编写代码比在Pthreads中更快吗? - user1132648
@Nunoxic 是的,但是pThreads可以做到OpenMP所能做到的一切(尽管开发代码可能更加困难),而相反地,有些事情OpenMP无法做到(或者不容易设计实现),但是pThreads可以。(作为一个现实生活中的例子,请看这个问题,在那里需要多个嵌套的OpenMP结构来设置一个单独的线程执行与其邻居不同的操作,而在pThreads实现中这样的事情不会造成任何问题) - François Févotte
经典的简单和灵活性案例。该死。谢谢 +1! - user1132648

1
为了补充已经出色的回答:在我编写pthread时,OpenMP通常比我更好地并行化我的代码。鉴于OpenMP也更容易,如果这是我的选择,我总是选择它。我猜测如果你正在问这个问题,你不是一个pthread专家,所以我建议使用OpenMP而不是pthread。

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