multithreading - Haskell 轻量级线程开销和在多核上的使用

标签 multithreading haskell concurrency multicore lightweight-processes

我一直在读《Real World Haskell》一书,关于并发和并行的章节。我的问题如下:

  • 由于 Haskell 线程实际上只是一个“真实”操作系统线程内的多个“虚拟”线程,这是否意味着创建大量线程(例如 1000 个)不会对性能产生巨大影响?也就是说,我们是否可以说使用 forkIO 创建 Haskell 线程所产生的开销(几乎)可以忽略不计?如果可能,请提供实际例子。

  • 轻量级线程的概念是否会妨碍我们利用多核架构的优势?据我了解,两个 Haskell 线程不可能在两个单独的核心上同时执行,因为从操作系统的角度来看,它们实际上是一个线程。或者 Haskell 运行时是否做了一些巧妙的技巧来确保可以使用多个 CPU?

最佳答案

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

sparks/threads/workers/cores

具体:

does this mean that creating a lot of them (like 1000) will not have a drastic impact on performance?

嗯,creating 1,000,000 of them当然是可能的。 1000 block 太便宜了,根本看不出来。您可以在线程创建基准测试中看到,例如“线程环”GHC is very, very good .

Doesn't the concept of lightweight threads prevent us from using the benefints of multicore architectures?

一点也不。 GHC has been running on multicores自 2004 年以来。多核运行时的当前状态是 tracked here.

它是如何做到的?阅读此架构的最佳位置是论文 "Runtime Support for Multicore Haskell" :

The GHC runtime system supports millions of lightweight threads by multiplexing them onto a handful of operating system threads, roughly one for each physical CPU. ...

Haskell threads are executed by a set of operating system threads, which we call worker threads. We maintain roughly one worker thread per physical CPU, but exactly which worker thread may vary from moment to moment ...

Since the worker thread may change, we maintain exactly one Haskell Execution Context (HEC) for each CPU. The HEC is a data structure that contains all the data that an OS worker thread requires in order to execute Haskell threads

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

threadscope

关于multithreading - Haskell 轻量级线程开销和在多核上的使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5847642/

相关文章:

haskell - 函数组合中的类型推导

haskell - 如何使用 Data.Reify 来具体化数据列表?

Java 并发和多线程

ios - 如何在 NSInvocationOpreation 中传递对象

multithreading - 通过克隆数据结构进行并发读取和写入?

mysql - 我是否正确计算了 MySQL 数据库的最大连接限制?

haskell - 我可以将类型类字典显式传递给函数吗?

Java:一个去重的延时队列

java - 使用 FutureTask 比 Callable 有什么优势?

c - 仅在 pthread 初始化时发生段错误