Haskell轻量级线程开销并用于多核

时间:2011-05-01 09:43:22

标签: multithreading haskell concurrency multicore lightweight-processes

我一直在阅读“真实世界Haskell”一书,关于并发和并行的章节。我的问题如下:

  • 由于Haskell线程实际上只是一个“真正的”OS线程中的多个“虚拟”线程,这是否意味着创建它们(如1000)不会对性能产生重大影响?即,我们可以说用forkIO创建Haskell线程所产生的开销几乎可以忽略不计吗?如果可能的话,请带上典型的例子。

  • 轻量级线程的概念是否阻止我们使用多核架构的好处?据我所知,两个Haskell线程不可能在两个独立的内核上并发执行,因为从操作系统的角度来看,它们实际上是一个单独的线程。或者Haskell运行时是否做了一些聪明的技巧来确保可以使用多个CPU?

3 个答案:

答案 0 :(得分:83)

GHC的运行时提供了一个支持数十亿个火花的执行环境,数千个轻量级线程,可以分布在多个硬件核心上。使用-threaded进行编译,并使用+RTS -N4标志设置所​​需的核心数。

sparks/threads/workers/cores

具体做法是:

  

这是否意味着创建很多(如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.。这里,例如运行二元树基准:

threadscope

答案 1 :(得分:14)

  • Warp网络服务器广泛使用这些轻量级线程来获取really good performance。请注意,其他Haskell Web服务器也吸引了竞争对手:这更像是“Haskell好”而不是“Warp很好。”

  • Haskell提供了一个多线程运行时,可以跨多个系统线程分发轻量级线程。它适用于最多4个内核。过去,有一些性能问题,尽管这些问题正在积极开展。

答案 2 :(得分:4)

创建1000个流程相对较轻;不要担心这样做。至于性能,你应该只对它进行基准测试。

如前所述,多核工作正常。通过在不同的OS线程上进行调度,可以同时运行多个Haskell线程。