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

58 concurrency multithreading haskell multicore lightweight-processes

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

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

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

Don*_*art 85

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

火花/线程/工人/芯

特别:

这是否意味着创建很多(如1000)不会对性能产生重大影响?

那么,创造1,000,000个肯定是可能的.1000是如此便宜,甚至不会出现.你可以在线程创建基准测试中看到,例如GHC非常非常好的 "线程环" .

轻量级线程的概念是否阻止我们使用多核架构的好处?

一点也不.自2004 以来,GHC一直在运行多核.此处跟踪多核运行时的当前状态.

它是如何做到的?阅读此架构的最佳位置是文章"多核Haskell的运行时支持":

GHC运行时系统通过将它们多路复用到少数操作系统线程上来支持数百万个轻量级线程,每个物理CPU大约有一个....

Haskell线程由一组操作系统线程执行,我们称之为工作线程.我们每个物理CPU只维护一个工作线程,但确切的工作线程可能会随时变化......

由于工作线程可能会发生变化,因此我们只为每个CPU维护一个Haskell执行上下文(HEC).HEC是一种数据结构,包含OS工作线程为执行Haskell线程所需的所有数据

您可以通过threadscope监视正在创建的线程以及它们执行的位置..在这里,例如运行二叉树基准测试:

threadscope


Mic*_*man 14

  • Warp webserver广泛使用这些轻量级线程来获得非常好的性能.请注意,其他Haskell Web服务器也吸引了竞争对手:这更像是"Haskell很好"而不是"Warp很好".

  • Haskell提供了一个多线程运行时,可以跨多个系统线程分发轻量级线程.它适用于最多4个内核.过去,虽然正在积极研究这些问题,但仍存在一些性能问题.

  • 我相信迈克尔所指的问题是IO管理器的体系结构不适合扩展到几个核心之外.特别是,它应该每个核心使用一个IO管理器线程.因此,这不是运行时问题,并且它不会影响CPU密集型工作负载的扩展,但IO密集型应用程序(如Web服务器)可能会遇到瓶颈.据我所知,还没有人做过彻底的分析. (8认同)
  • 您是否对提及的> 4核心的性能问题有任何参考? (3认同)
  • 是的,Snap也看到了这个问题.它最近变得更好,但似乎在5或6个线程后可能会下降.上次我做基准测试Warp的绝对性能比Snap快,但是Snap的扩展速度超过4核.这可能不足以推断具体的东西,但我认为这很有趣. (2认同)