Haskell轻量级线程开销并用于多核
我一直在阅读“真实世界Haskell”一书,关于并发性和并行性的一章。 我的问题如下:
-
由于Haskell线程真的只是一个“真正的”OS线程中的多个“虚拟”线程,这是否意味着创build很多(如1000)不会对性能产生严重影响? 也就是说,我们可以说用
forkIO
创build一个Haskell线程的开销(几乎)可以忽略不计? 如果可能,请带上切实的例子。 -
轻量级线程的概念不妨碍我们使用多核架构的好处吗? 据我所知,两个Haskell线程不可能同时在两个独立的内核上执行,因为从操作系统的angular度来看,它们确实是一个单一的线程。 还是Haskell运行时做了一些巧妙的技巧,以确保可以使用多个CPU?
GHC的运行时提供了一个执行环境,支持数十亿个火花,数以千计的轻量级线程,可以分布在多个硬件核心上。 使用-threaded
编译并使用+RTS -N4
标志来设置所需的内核数量。
特别:
这是否意味着创造很多(如1000)不会对性能产生重大影响?
那么, 创造100万是肯定可能的。 1000是如此便宜,甚至不会出现。 您可以在线程创build基准中看到GHC非常非常好的 “线程环”。
轻量级线程的概念不妨碍我们使用多核架构的好处吗?
一点也不。 自2004 年以来, GHC一直在运行多核 。多核运行时的当前状态在此处被跟踪。
它是如何做到的? 阅读这个架构的最佳地点在文章“多核Haskell的运行时支持”中 :
GHC运行时系统通过将数千个轻量级线程复用到less数几个操作系统线程上,每个物理CPU大约一个线程支持。 …
Haskell线程由一组操作系统线程执行,我们称之为工作线程。 我们每个物理CPU大致维护一个工作线程,但是每个工作线程可能会随时变化。
由于工作线程可能会改变,我们只为每个CPU维护一个Haskell执行上下文(HEC)。 HEC是一个数据结构,包含OS工作线程为了执行Haskell线程而需要的所有数据
你可以通过threadscope监视正在创build的线程,以及它们在哪里执行。 。 在这里,例如运行二叉树基准:
-
Warp webserver广泛使用这些轻量级线程来获得非常好的性能 。 请注意,其他Haskellnetworking服务器也吸引了竞争对手:这更像是“Haskell是好的”,而“Warp是好的”。
-
Haskell提供了一个multithreading的运行时,可以在多个系统线程中分配轻量级的线程。 它可以很好地运行多达4个内核。 过去,有一些性能问题,虽然那些正在积极的工作。
创build1000个进程的权重相对较轻; 不要担心这样做。 至于performance,你应该只是基准。
如前所述,多核心工作得很好。 一些Haskell线程可以在不同的OS线程上同时运行。