Erlang的并行性什么时候克服了它在数值计算方面的弱点?

时间:2009-08-20 20:11:35

标签: performance erlang

随着最近围绕并行计算的大肆宣传,我一直在思考很多关于并行性,数字运算,集群等等......

我开始阅读Learn You Some Erlang。随着越来越多的人学习(包括我自己),Erlang以一种非常令人印象深刻,优雅的方式处理并发。

然后作者声称Erlang是not ideal for number crunching。我可以理解像Erlang这样的语言比C慢,但是并发模型似乎非常适合图像处理或矩阵乘法之类的东西,即使作者特别说它不是。

真的那么糟糕吗?是否有一个临界点,Erlang的力量克服了当地的速度弱点?正在采取什么措施来应对速度?

要明确:我不是要开始辩论;我只是想知道。

5 个答案:

答案 0 :(得分:46)

将并行性视为原始数字运算能力是错误​​的。 Erlang更接近于集群计算机的工作方式,比如GPU或经典的超级计算机。

在现代GPU和旧式超级计算机中,性能完全与矢量化算法,专用计算硬件和处理单元之间的低延迟通信有关。由于通信延迟很低并且每个单独的计算单元都非常快,理想的使用模式是用数据加载机器的RAM并立即将其全部压缩。此处理可能涉及在节点之间传递大量数据,如图像处理或3D中所发生的那样,其中有许多CPU绑定任务要将数据从输入形式转换为输出形式。当您经常需要转到磁盘,网络或其他慢速I / O通道获取数据时,这种类型的计算机是一个糟糕的选择。这至少会耗费一个昂贵的专用处理器,并且可能还会阻塞数据处理管道,因此也无法完成任何工作。

如果您的程序需要大量使用慢速I / O通道,那么更好的类型的计算机就是具有许多廉价独立处理器的计算机,例如集群。您可以在一台计算机上运行Erlang,在这种情况下,您可以在该计算机中获得类似集群的功能,或者您可以在实际的硬件集群上轻松运行它,在这种情况下,您可以拥有一组集群。在这里,通信开销仍然使处理单元闲置,但由于您在计算硬件的每个位上运行了许多处理单元,因此Erlang可以立即切换到其他进程之一。如果发生整个机器正在等待I / O,您仍然可以在硬件集群中拥有可以独立运行的其他节点。当通信开销太高以至于每个节点都在某个其他节点上等待,或者对于一般I / O时,此模型只会中断,在这种情况下,您需要更快的I / O或更多节点,这两个节点都是Erlang自然利用的的。

通信和控制系统是Erlang的理想应用程序,因为每个单独的处理任务占用很少的CPU,并且偶尔需要与其他处理节点通信。大多数情况下,每个进程都是独立运行的,每个进程只占CPU功耗的一小部分。这里最重要的是能够有效地处理成千上万的这些。

绝对需要经典超级计算机的经典案例是天气预报。在这里,您将大气分成立方体并进行物理模拟以找出每个立方体中发生的情况,但您不能使用集群,因为空气在每个立方体之间移动,因此每个立方体不断与其相邻的6个邻居进行通信。 (Air不会通过立方体的边缘或角落,无限精细,因此它不会与其他20个相邻的立方体对话。)在群集上运行,无论是在其上运行Erlang还是其他系统,它立即变成I / O界限。

答案 1 :(得分:11)

  

Erlang的力量是否有一个临界点可以克服当地的速度弱点?

嗯,当然有。例如,当试图找到一万亿个数字的中位数:):

http://matpalm.com/median/question.html

就在您发布之前,我碰巧注意到这是erlang.reddit.com上的第1号帖子。

答案 2 :(得分:10)

几乎所有语言都可以并行化。在某些语言中它很简单,在其他语言中它是一个痛苦的屁股,但它可以做到。如果要在网格中的8000个CPU上运行C ++程序,请继续!你可以做到这一点。它之前已经完成了。

Erlang不会做任何其他语言无法做到的事情。如果运行Erlang程序的单个CPU的效率低于运行C ++程序的同一个CPU,那么运行Erlang的200个CPU也将比运行C ++的200个CPU慢。

Erlang 做的做的是使这种并行易于使用。它节省了开发人员的时间并减少了错误的机会。

所以我要说不,没有引爆点,Erlang的并行性可以让它超越另一种语言的数字运算强度。

Erlang得分在哪里更容易向外扩展并正确执行。但是如果你愿意花费额外的开发时间,它仍然可以用其他语言更好地完成数字运算。

当然,让我们不要忘记语言没有速度的好点。 一个足够好的Erlang编译器可以产生完美的最佳代码。一个足够糟糕的C编译器会产生比其他任何东西运行得慢的代码。

答案 3 :(得分:6)

迫使Erlang更快地执行数字代码。例如,HiPe编译器编译为本机代码而不是BEAM字节码,它可能对浮点上的代码进行最有效的优化,以避免装箱。这对浮点代码非常有用,因为它可以直接在FPU寄存器中存储值。

对于Erlang的大部分用法,Erlang的速度非常快。他们使用Erlang编写永远在线的控制系统,其中最重要的速度测量是低延迟响应。负载下的性能往往受IO限制。这些用户倾向于远离HiPe,因为它在调试实时系统方面不够灵活/可塑。

现在具有128Gb RAM的服务器并不常见,并且没有理由他们会获得更多内存,一些IO绑定问题可能会转移到有点CPU限制。这可能是一个驱动因素。

您应该关注HiPe进行开发。


你的图像操作和矩阵乘法的例子在我看来是对Erlang的非常糟糕的匹配。这些是受益于矢量/ SIMD操作的示例。 Erlang不擅长并行(一次对多个值做同样的事情)。

Erlang进程是MIMD,多个指令多个数据。 Erlang在模式匹配和递归循环之后做了很多分支。这会导致CPU指令流水线化。

针对严重并行问题的最佳架构是GPU。对于使用函数式语言编程GPU,我发现使用Haskell创建针对它们的程序的最佳潜力。 GPU基本上是从输入数据到输出数据的纯函数。请参阅Haskell中的Lava项目以创建FPGA电路,如果可以在Haskell中如此干净地创建电路,那么为GPU创建程序数据就不会那么困难。

Cell架构对于可矢量化的问题也非常好。

答案 4 :(得分:1)

我认为更广泛的需要是指出并行性不一定或甚至通常与速度有关。

关于如何表达活动序列被部分排序的算法或程序。