我一直在阅读“真实世界Haskell”一书,关于并发和并行的章节。我的问题如下:
由于Haskell线程实际上只是一个“真正的”OS线程中的多个“虚拟”线程,这是否意味着创建它们(如1000)不会对性能产生重大影响?即,我们可以说用forkIO
创建Haskell线程所产生的开销几乎可以忽略不计吗?如果可能的话,请带上典型的例子。
轻量级线程的概念是否阻止我们使用多核架构的好处?据我所知,两个Haskell线程不可能在两个独立的内核上并发执行,因为从操作系统的角度来看,它们实际上是一个单独的线程。或者Haskell运行时是否做了一些聪明的技巧来确保可以使用多个CPU?
答案 0 :(得分:83)
GHC的运行时提供了一个支持数十亿个火花的执行环境,数千个轻量级线程,可以分布在多个硬件核心上。使用-threaded
进行编译,并使用+RTS -N4
标志设置所需的核心数。
具体做法是:
这是否意味着创建很多(如1000)不会对性能产生重大影响?
嗯,creating 1,000,000 of them肯定是可能的。 1000是如此便宜,甚至不会出现。您可以在线程创建基准测试中看到,例如GHC is very, very good。
的“线程环”轻量级线程的概念是否阻止我们使用多核架构的好处?
完全没有。自2004年以来GHC has been running on multicores。多核运行时的当前状态为tracked here.
它是如何做到的?阅读此架构的最佳位置在论文"Runtime Support for Multicore Haskell":
中GHC运行时系统支持数百万个轻量级线程 通过将它们复用到少数操作系统线程上, 每个物理CPU大约一个。 ...
Haskell线程由一组操作系统执行 线程,我们称之为工作线程。我们大致维持一个 每个物理CPU的工作线程,但究竟是哪个工作线程 可能会随时变化......
由于工作线程可能会发生变化,我们只保留一个 每个CPU的Haskell执行上下文(HEC)。 HEC是一个 包含OS工作线程的所有数据的数据结构 需要执行Haskell线程
您可以监控正在创建的线程及其执行位置via threadscope.。这里,例如运行二元树基准:
答案 1 :(得分:14)
Warp网络服务器广泛使用这些轻量级线程来获取really good performance。请注意,其他Haskell Web服务器也吸引了竞争对手:这更像是“Haskell好”而不是“Warp很好。”
Haskell提供了一个多线程运行时,可以跨多个系统线程分发轻量级线程。它适用于最多4个内核。过去,有一些性能问题,尽管这些问题正在积极开展。
答案 2 :(得分:4)
创建1000个流程相对较轻;不要担心这样做。至于性能,你应该只对它进行基准测试。
如前所述,多核工作正常。通过在不同的OS线程上进行调度,可以同时运行多个Haskell线程。