我正在使用c ++为我的计算动力学研究开发一些代码。我的代码解决了稀疏和密集的矩阵,生成网格,并在最微不足道的意义上做类似的操作。我需要并行化我的代码以减少计算时间并为此目的使用OpenMP。
但仔细研究了商用代码,比如ANSYS CFX,我遇到了该软件中使用的并行化方案是MPICH2,它是MPI的一种实现方式。
所以你有很多并行化工具/ API:
我使用了其中一些工具,并设法在本地计算机上使用每个工具获得100%的CPU使用率。
在选择合适的并行化工具时,我不知道应该注意什么标准。什么样的应用需要哪种工具?上述任何一项可用于研究目的吗?其中哪些主要用于商业软件?
答案 0 :(得分:7)
至于这种类型的许多问题,没有一个真正明确的答案。你不能真正说出什么更好,因为答案总是“它取决于”。关于你在做什么,你的代码是如何编写的,你的可移植性要求是什么等等。
点击列表:
用什么?我没有答案,只是尝试选择你觉得更舒服的东西(看看Boost Threads)。请注意,不知何故,你可以混合它们,例如OpenMP + MPI,MPI + TBB甚至MPI + PLL)。我倾向于PPL但是如果你正在开发一个真实世界的应用程序,你可能需要一个长时间的测试来决定什么是更好的。实际上我喜欢Concurrency Runtime(PPL的基础),因为它是“水平的”,它提供了一个用于并行计算的基本框架(带有结构和算法)和许多“垂直”包(Agents,PPL,{{ 3}})。
这就是说当你的计算并行时,你可能需要提高一些CPU密集型例程的性能。你可以考虑使用GPU来完成这项任务,我认为它将为TPL大规模并行计算提供最佳功能(当然我更喜欢short而不是专有OpenCL即使CUDA表现CUDA)。实际上,如果您对此主题感兴趣,甚至可以查看may be higher。
答案 1 :(得分:3)
考虑这是对Adriano答案的扩展评论(和扩展)。
OpenMP非常容易掌握和使用,它具有很好的功能,即串行和并行可执行文件都可以从同一个源代码生成。如果您需要将现有的串行代码转换为并行代码,它还允许您采用渐进式并行化路径。然而,OpenMP有一些缺点。首先,它仅针对严重限制其可扩展性的共享内存机器,尽管现在可以使用大型x86 SMP机器(例如,我们的QPI耦合Xeon系统具有128个CPU内核,在我们的集群安装中共享最多2 TiB的共享RAM,专门针对大型OpenMP工作)。 其次,它的编程模型太简单,无法实现一些高级概念。但我会说这是模型的优势而不是缺点,因为它保持了OpenMP的简洁。
MPI是当今传递API的事实上的标准消息。它得到广泛支持,并在各种并行体系结构上运行。它的分布式内存模型对底层硬件几乎没有任何限制(除了具有低延迟和高带宽的网络互连),这使它可以扩展到数十万个CPU内核。虽然算法本身可能不具备可移植的可伸缩性(例如,一个MPI程序可能在Blue Gene / P上非常有效地运行并且在InfiniBand集群上非常慢),但MPI程序在源级别上也是非常便携的。 MPI有一个严重的缺点 - 它的SPMD(单程序多数据)模型需要代表程序员进行很多精神分裂的思考,并且比OpenMP更难掌握。将串行算法移植到MPI绝不像OpenMP那样容易,有时需要完全重写才能实现高并行效率。也不可能采用渐进式并行化方法并轻松维护可以生成串行和并行可执行文件的代码库。 MPI有一个有趣的特性 - 因为它完全分离了在不同节点上运行的程序的不同部分,并为网络提供了一个抽象接口,它允许异构计算。若干MPI实现(例如,Open MPI)提供异构支持,其允许不仅混合在不同OS下运行的节点而且混合具有不同" bitness"的CPU。和endianness。
英特尔TBB就像类固醇上的OpenMP一样。它提供了更丰富的基于内核的编程模型,使其更接近其他并行编程范例,如CUDA或OpenCL。它在适用性和可扩展性方面大量使用C ++ STL算法。它也应该是编译器中立的,原则上应该与英特尔C ++编译器,GNU g ++和MSVC一起使用。 ITBB还使用任务"窃取"意识形态,如果不采取预防措施,可能会使以前的范例容易出现计算上的不和谐。
Pthreads是最现代Unix相似的便携式线程接口(例如FreeBSD,Mac OS X,Linux等)。它只是一个线程库,面向人们可以想象的最常见的用例。它提供很少甚至没有并行结构,并且必须在它上面明确地编程它们,例如,即使是简单的循环迭代分布,也必须手动编码OpenMP。 Pthreads与Unix完全相同的是Win32线程对Windows的影响。
(我会跳过Microsoft TPP,因为我不太了解该库)
混合这些概念显然是未来的方式,因为单个节点逐渐变得越来越多核心。大多数算法都可以实现多级并行,并且可以使用MPI执行粗粒度并行(在多个集群节点上运行),而OpenMP或ITBB可用于执行单个节点计算的细粒度分区。共享内存编程通常可以更好地利用内存资源,因为它们都在线程之间共享,而缓存重用之类的东西可以大大加快缓存。 MPI也可用于编程多核SMP或NUMA机器,但每个MPI进程都是一个独立的OS进程,具有自己的虚拟地址空间,这意味着可能需要复制大量(配置)数据。 MPI人员正在努力改进标准,以允许它作为线程和MPI端点运行MPI进程"可能会在即将推出的MPI标准版本3.0中结束。
我建议选择最接近您编程背景的那个。如果你是一个狂热的C ++程序员并呼吸抽象,那么选择英特尔TBB(如果你进入.Net,则选择Microsoft PPL)。 OpenMP非常容易掌握并提供良好的性能,但在某种程度上是简单的。它仍然是在Fortran中编写多线程代码的唯一广泛可用和使用的机制。 MPI有一个陡峭的学习曲线,但如果您的程序超出单个计算节点可以提供的程度,则可以随后用螺栓固定。