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

发布于 2024-11-04 01:43:49 字数 363 浏览 7 评论 0原文

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

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

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

I've been reading the "Real World Haskell" book, the chapter on concurrency and parallelism. My question is as follows:

  • Since Haskell threads are really just multiple "virtual" threads inside one "real" OS-thread, does this mean that creating a lot of them (like 1000) will not have a drastic impact on performance? I.e., can we say that the overhead incurred from creating a Haskell thread with forkIO is (almost) negligible? Please bring pactical examples if possible.

  • Doesn't the concept of lightweight threads prevent us from using the benefints of multicore architectures? As I understand, it is not possible for two Haskell threads to execute concurrently on two separate cores, because they are really one single thread from the operating system's point of view. Or does the Haskell runtime do some clever tricks to ensure that multiple CPU's can be made use of?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

风吹短裙飘 2024-11-11 01:43:49

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

sparks/threads/workers/cores

具体来说:

这是否意味着创建大量(例如 1000 个)不会对性能产生巨大影响?

好吧,创建 1,000,000 个当然是可能的。 1000块太便宜了,根本看不出来。您可以在线程创建基准测试中看到,例如“线程环”,GHC 是非常非常好

轻量级线程的概念是否会妨碍我们利用多核架构的优势?

一点也不。 GHC 自 2004 年以来一直在多核上运行。多核运行时的当前状态是在此处进行跟踪。

它是如何做到的?阅读此架构的最佳位置是论文“Runtime Support for多核 Haskell”

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

Haskell线程是由一组操作系统执行的
线程,我们称之为工作线程。我们维持大约一个
每个物理 CPU 的工作线程,但具体是哪个工作线程
可能会随时发生变化...

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

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

threadscope

GHC's runtime provides an execution environment supporting billions of sparks, thousands of lightweight threads, which may be distributed over multiple hardware cores. Compile with -threaded and use the +RTS -N4 flags to set your desired number of cores.

sparks/threads/workers/cores

Specifically:

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

Well, creating 1,000,000 of them is certainly possible. 1000 is so cheap it won't even show up. You can see in thread creation benchmarks, such as "thread ring" that GHC is very, very good.

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

Not at all. GHC has been running on multicores since 2004. The current status of the multicore runtime is tracked here.

How does it do it? The best place to read up on this architecture is in the paper, "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

You can monitor your threads being created, and where they're executing, via threadscope.. Here, e.g. running the binary-trees benchmark:

threadscope

时光匆匆的小流年 2024-11-11 01:43:49
  • The Warp webserver uses these lightweight threads extensively to get really good performance. Note that the other Haskell web servers also smoke the competition: this is more of a "Haskell is good" than "Warp is good."

  • Haskell provides a multithreaded runtime which can distribute lightweight threads across multiple system threads. It works very well for up to 4 cores. Past that, there are some performance issues, though those are being actively worked on.

烈酒灼喉 2024-11-11 01:43:49

创建1000个进程是相对轻量级的;不用担心这样做。至于性能,你应该只对其进行基准测试。

正如之前所指出的,多核工作得很好。多个 Haskell 线程可以通过调度在不同的操作系统线程上同时运行。

Creating 1000 processes is relatively light weight; don't worry about doing it. As for performance, you should just benchmark it.

As has been pointed out before, multiple cores work just fine. Several Haskell threads can run at the same time by being scheduled on different OS threads.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文