Haskell 多线程有多难?
我听说在 Haskell 中,创建多线程应用程序就像采用标准 Haskell 应用程序并使用 -threaded
标志对其进行编译一样简单。然而,其他情况描述了在实际源代码中使用 par
命令。
Haskell 多线程的状态如何?引入程序有多容易?是否有一个很好的多线程教程来介绍这些不同的命令及其用途?
I have heard that in Haskell, creating a multi-threaded application is as easy as taking a standard Haskell application and compiling it with the -threaded
flag. Other cases, however, have described the use of a par
command within the actual source code.
What is the state of Haskell multi-threading? How easy is it to introduce into programs? Is there a good multi-threading tutorial that goes over these different commands and their uses?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
成熟。该实施已有约 15 年历史,事务内存长达 5 年。 GHC 是一种广泛使用的编译器,拥有大量开源支持和商业支持。
这取决于算法。有时可以单行使用
par
来获得并行性。有时必须开发新的算法。一般来说,在 Haskell 中引入安全并行性和并发性比在典型语言中更容易,而且性能也很好。Haskell 中有 3 种主要的并行和并发编程模型。
par
实现隐式并行,数据并行这些是主要内容。在所有情况下,您都使用 -threaded 进行编译以使用多核运行时,但是并行处理特定问题的容易程度取决于您使用的算法以及您从该列表中采用的并行编程模型。
这是主要并行的介绍Haskell 中的编程模型,以及如何实现加速。
我认为 Real World Haskell 第 24 章 是一个很好的教程。
Mature. The implementation is around 15 years old, with transactional memory for 5 years. GHC is a widely used compiler, with large open source support, and commercial backing.
This depends on the algorithm. Sometimes it can be a one line use of
par
to gain parallelism. Sometimes new algorithms must be developed. In general it will be easier to introduce safe parallelism and concurrency in Haskell, than in typical languages, and performance is good.There are 3 major parallel and concurrent programming models in Haskell.
par
These are the main things. In all cases you compile with -threaded to use the multicore runtime, but how easy it is to parallelise a particular problem depends on the algorithm you use, and the parallel programming model you adopt from that list.
Here is an introduction to the main parallel programming models in Haskell, and how to achieve speedups.
I think Chapter 24 of Real World Haskell is a good tutorial.
还有并发术语。
如果不对代码进行任何更改,您的 haskell rts 将尝试将它们用于某些内部进程,但是要在您的应用程序中使用,您应该给出由
par b (fab)
完成的提示,这会强制 Haskell 不这样做即使f
不需要它来获得结果,也懒得计算b
。不对每个需要其所有参数的函数(例如
a+b
)执行此操作的原因之一是同步(安排计算和等待结果)会带来一些开销,而您可能不会想要为(2*3)+(3*4)
花费额外的费用,只是因为您可以并行计算乘法。而且您可能会失去一些缓存命中或类似的东西或当您在单个处理器上执行此操作时完成的优化(即您无论如何都需要将结果从一个处理器传递到另一个处理器)。当然,使用
par
的代码很丑陋,当您折叠列表或其他带有轻量子元素的数据结构时,您可能需要计算该轻量元素的一些块以确保开销/ calc 会非常小。要解决这个问题,您可以查看parallel。还有数据并行 Haskell (DPH)。
如果您的程序更多的是关于 IO monad,那么您肯定需要进行许多更改。请参阅
forkIO
、软件事务内存 (STM) 以及来自 并发类别There is also concurrency term.
Without any changes in code your haskell rts will try to use them for some internal process, but to use in your application you should give a hint that's done by
par b (f a b)
which forces Haskell to be not so lazy on caculation ofb
even iff
will not require it for result.One of the reason to not do that for every function which require its all its arguments (like
a+b
) is that synchronization (scheduling calculations and waiting for results) gives some overhead and you probably don't want to spend extra-ticks for(2*3)+(3*4)
just because you can calculate multiplications in parallel. And you probably will loose some cache-hits or something like this or optimizations which is done when you do that on single processor (i.e. you'll need to pass result from one processor to another anyway).Of course code which is uses
par
is ugly and when you fold list or some other data structures with light sub-elements you'll probably want to calculate some chunks of that light elements to make sure that overhead/calc will be really small. To resolve that you can look at parallel.There is also Data Parallel Haskell (DPH).
If your program is more about IO monad than you definitely need many changes. See
forkIO
, Software Transactional Memory (STM) and many others from Concurrency category