函数式语言本质上是否比它们的OO或命令式表兄弟更具可并行性?

时间:2009-03-11 02:51:33

标签: parallel-processing functional-programming

我一直在阅读并思考这个问题。嗡嗡声似乎是在多核未来,功能语言将变得更受欢迎。我是函数式编程的相对noob。我唯一的接触是学术性的,并没有足够的复杂性来真正让这种语言顺其自如。

因此,据我所知,纯函数可以轻松透明地并行化。这是一个很棒的功能,因为它意味着编写线程代码没有麻烦。但是,它似乎没有给串行代码提供太多帮助。

Example:

fooN( ... (foo3(foo2(foo1(0)))))
像这样的串行呼叫似乎是一个常见的,有时是不可避免的问题。对我来说,这些是并行化如此困难的根本原因。有些任务只是(或似乎是)高度连续的。拥有“功能性思维”是否可以让您更好地分解一些看似串行的任务?现有的任何功能语言是否提供透明机制以更好地并行化高度串行代码?最后,函数式语言本质上是否比OO或命令式语言更具可并行性,为什么?

2 个答案:

答案 0 :(得分:8)

由于纯函数,函数式语言比命令式和OO语言更具可并行性。但是,你是绝对正确的,如果你有这些类型的数据依赖,你不能并行化它。函数式编程的主要价值在于使代码中存在的并行性更易于发现和推理,因为只有数据依赖性而非共享的可变状态才会妨碍。

事实上,因为大多数凡人致命的程序员都难以使用纯函数式语言,并且因为完全不允许可变状态的严厉政策可能效率低下,所以关于允许单个函数体被强制写入的想法存在一些嗡嗡声,但不允许跨职能部门的副作用。换句话说,要并行化的所有函数都必须是纯粹的。然后,您可以使用局部变量的可变状态来使代码更容易编写和更高效,但仍然允许安全,轻松地自动并行化对这些纯函数的调用。例如,正在研究D语言的2.0分支。

答案 1 :(得分:6)

主要是副作用。如果编译器知道某些代码没有副作用,它可以根据代码结构进行优化,以并行运行其中一些。

考虑使用C#/这是半功能的linq:

var someValues = from c in someArray
                where // some  comparisson with no side effects
                select c;

您正在指定要执行的操作的意图,如果编译器知道表达式的每个部分都没有副作用,则可以安全地分配数组的不同部分以在不同的核心上进行处理。实际上有一个.AsParalell将会出现并行linq(plinq),这将实现这一点。问题在于,它无法强制执行无副作用(位于不支持它的语言/框架上),如果开发人员不知道,这可能会变得非常难看。因此,他们明确表示,但你可以看到在此过程中造成麻烦。