Haskell多线程编程有多难?

69

我听说在 Haskell 中创建多线程应用程序就像使用标准的 Haskell 应用程序并将其编译为带有 -threaded 标志一样简单。然而,其他情况下则需要在实际源代码中使用 par 命令。

Haskell 多线程的现状如何?将其引入程序有多容易?是否有一个好的多线程教程来介绍这些不同的命令及其用途?


1
我相信Simon Marlow的《Haskell并行与并发编程》通常被认为是这个主题最好的入门教材。 - Chris Martin
2个回答

67

什么是Haskell多线程的状态?

成熟。 实现有约15年历史,事务内存则有5年历史。 GHC是广泛使用的编译器,并获得了大量的开源支持和商业支持。

将其引入程序有多容易?

这取决于算法。 有时可以通过一行par使用实现并行化。 有时必须开发新算法。 通常,在Haskell中引入安全的并行性和并发性要比在典型语言中容易,而且性能很好。

是否有一个好的多线程教程介绍这些不同的命令及其用途?

Haskell中有3种主要的并行和并发编程模型:

  • 隐式并行性:通过 par
  • 显式并发和并行化:通过forkIO / MVars和软件事务内存
  • 数据并行性:通过DPH库

这些是主要的内容。 在所有情况下,您都需要使用-threaded进行编译以使用多核运行时,但是如何轻松地将特定问题并行化取决于您使用的算法和从该列表采用的并行编程模型。

这里是介绍Haskell中主要的并行编程模型以及如何实现加速。

我认为Real World Haskell第24章是一个很好的教程。


18

还有一个并发术语。

在不修改代码的情况下,您的Haskell RTS将尝试将它们用于某些内部进程,但要在应用程序中使用它们,您应该使用par b(f a b)来给出提示,这样即使f不需要结果,Haskell 也不会对计算b过于懒惰。

不为每个需要其所有参数(例如a+b)的函数执行此操作的原因之一是同步(调度计算和等待结果)会增加一些开销,您可能不希望为(2*3)+(3*4)花费额外的时钟周期,只因为您可以并行计算乘法。而且您可能会失去一些缓存命中或类似于在单处理器上执行时所做的优化(即无论如何都需要将结果从一个处理器传递到另一个处理器)。

当然,使用par的代码很丑陋,当您使用轻型子元素折叠列表或其他数据结构时,您可能希望计算那些轻型元素的一些块,以确保开销/计算确实很小。要解决这个问题,可以查看parallel

还有数据并行Haskell(DPH)。

如果您的程序更多关于IO单子,那么您肯定需要进行许多更改。请参阅forkIO软件事务内存(STM)以及来自并发类别的其他内容。


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