我们使用哪些并行编程API?
考虑到当今多核和多处理硬件的巨大重要性,试图掌握人们当前实际如何编写并行代码。在我看来,主要的范例是pthreads(POSIX线程),它在Linux上是本机的,而在Windows上可用。 HPC人们倾向于使用OpenMP或者MPI,但是在StackOverflow上似乎并不多。还是我们依赖Java线程,Windows线程API等,而不是可移植的标准?我们认为进行并行编程的推荐方式是什么?
还是我们正在使用更多奇特的东西,例如Erlang,CUDA,RapidMind,CodePlay,Oz,甚至是亲爱的老Occam?
澄清:我正在寻找一种可移植的解决方案,并适用于各种主机体系结构上的平台,例如Linux,各种unix。 Windows是一种罕见的情况,很好支持。因此Cand .net的范围实在太狭窄了,CLR是一项很酷的技术,但是他们可以为Linux主机发布它吗,以便它像JVM,Python,Erlang或者任何其他可移植语言一样流行。
基于C ++或者JVM的:可能是C ++,因为JVM往往会掩盖性能。
MPI:我也同意,即使HPC人士也将其视为一种难以使用的工具-但对于在128000处理器上运行的工具,它是解决不适用map / reduce问题的唯一可扩展解决方案。但是,消息传递具有很高的优雅度,因为它是唯一一种可以真正很好地扩展到本地内存/ AMP,共享内存/ SMP,分布式运行时环境的编程样式。
MCAPI是一个有趣的新竞争者。但我认为还没有人有时间对此进行任何实践经验。
因此,总的来说,情况似乎是存在许多我不知道的有趣的Microsoft项目,并且Windows API或者pthread是实践中最常见的实现。
解决方案
我们已经开始研究尚未发布的Microsoft并行扩展,但肯定显示出了潜力。
我使用ACE允许开发人员在任何平台上使用POSIX(或者Windows)样式的线程。
并行FX库(PFX)由Microsoft Research与Microsoft的CLR团队合作开发的托管并发库,用于将来的.NET Framework修订版。它由两部分组成:并行LINQ(PLINQ)和任务并行库(TPL)。它还由一组协调数据结构(CDS)组成,一组数据结构用于同步和协调并发任务的执行。该库于2007年11月29日作为CTP发布,并于2007年12月和2008年6月再次刷新。
虽然经验不是很多...
对于.Net,我非常成功地使用了RetLang。对于JVM,Scale很棒。
我建议使用OpenMP。 Microsoft已将其放入Visual C ++ 2005编译器中,因此得到了很好的支持,除了使用/ omp指令进行编译外,我们无需执行任何其他操作。
它简单易用,尽管显然它并不能为我们做任何事情,但是什么也做不了。我通常使用它来为并行循环运行而没有任何麻烦,对于更复杂的事情,我倾向于自己动手(例如,我有很久以前的代码,我曾进行过剪切,粘贴和修改)。
我们可以尝试看起来不错的Cilk ++,并拥有一本电子书"如何生存于多核软件革命"。
这两种系统都尝试并行化串行代码,即以尽可能简单的方式在所有内核上同时进行for循环和运行。它们往往不是通用线程库。 (例如,一份研究论文(pdf)描述了在openMP中实现的不同类型的线程池的性能,并建议应在它的产量和睡眠方面增加2个新操作。我认为它们在那里稍微有点OpenMP的不足)
正如我们提到的OpenMP,我假设我们是在谈论本机c ++,而不是Cor .NET。
另外,如果HPC人员(我认为是这种领域的专家)似乎正在使用OpenMP或者MPI,那么这就是我们应该使用的,而不是SO的读者群!
请注意,这里的答案将不是"实际使用"的统计上具有代表性的答案。我已经看到许多" X很好"的答案。
我亲自在许多项目上使用Windows线程。我广泛使用的其他API是pthreads。在HPC方面,使用它的人们仍然很重视MPI,它不是将C ++的所有优雅与Javascript的性能结合在一起。它之所以能够生存是因为没有其他合适的选择。一方面,它将失去紧密耦合的NUMA机器,另一方面将失去Google风格的map-reduce。 </ subjective>
+1代表PLINQ
Win32线程,线程池和光纤,同步对象
更多数据并行Haskell会很好,但是即使没有它,GHC> 6.6也具有通过Control.Parallel.Strategies轻松实现并行算法的令人印象深刻的能力。
我维护一个并发链接博客,该博客随着时间的推移涵盖了很多此类内容(并将继续这样做):
http://concurrency.tumblr.com
MPI并不像大多数人想象的那么难。如今,我认为多范例方法最适合并行和分布式应用程序。使用MPI进行节点间的通信和同步,并使用OpenMP或者PThreads进行更精细的并行化。为每台机器考虑MPI,为每个核心考虑OpenMP或者PThread。这似乎比在不久的将来为每个内核生成一个新的MPI Proc更好。
也许对于现在的双核或者四核,在计算机上为每个内核生成proc不会有那么多的开销,但是随着我们在越来越多的每台计算机上使用缓存和内存不足的内核时,使用共享内存模型会更合适。
Open CL怎么样?
我到目前为止只知道Java,那里的多线程支持对我来说效果很好。
在很大程度上取决于环境。
对于帕林老C,没有什么比POSIX更胜一筹了。
对于C ++,BOOST.ORG提供了一个很好的免费线程库。
Java只使用本机Java线程。
我们还可以查看除线程之外的其他实现并行性的方法,例如将应用程序划分为客户端和服务器进程以及使用异步消息进行通信。如果做得好,这可以在数十台服务器上扩展到成千上万的用户。
同样值得一提的是,如果我们使用的是Windows MFC,Gnome或者Qt窗口环境,则会自动处于多线程环境中。如果我们使用的是Apache ISS或者J2EE,则应用程序已在多线程多进程环境中运行。
我之所以使用OpenMP,主要是因为它具有简单性,可移植性和灵活性。它支持多种语言,甚至全能的C ++ / Cli :)
我使用MPI并非常喜欢它。它确实迫使我们考虑内存层次结构,但是以我的经验来看,无论如何对于高性能来说,考虑这些事情是很重要的。在许多情况下,MPI可以很大程度上隐藏在特定于领域的并行对象后面(例如,用于求解线性和非线性方程的PETSc)。
我编写的大多数并发程序都在Ada中,Ada完全支持该语言中的并行性。这样做的好处之一是并行代码可移植到具有Ada编译器的任何系统中。不需要特殊的库。
pycuda ...有点像25000个活动线程:) [通过记分板计划的扭曲]。 cuda 2具有流支持,所以我不确定会带来什么流。 CUDA Matlab扩展看起来很简洁,PLUTO和MIT即将发布的PetaBricks也是如此。
就其他人而言,缺少python的线程; MPI等非常复杂,并且我没有集群,但是我想它们可以实现它们的目标;我在进入公寓之前停止了编程(可能是一件好事)。
它本身不是并行的,也没有分布式模型,但是我们可以使用Clojure在JVM上编写高度并发的代码。随后,我们可以获得大量可用的Java库。我们将必须在clojure之上实现自己的并行算法,但这应该相对容易。我重复一遍,它还没有分布式模型。
来自glibc库的gthreads http://library.gnome.org/devel/glib/stable/glib-Threads.html可以编译为pthreads,因此我们不会失去任何性能。它们还为我们提供了非常强大的线程池,以及线程之间的消息队列。我已经成功地使用了它们多次,并对可用的功能感到非常满意。