Haskell轻量级线程开销和在多核上使用 [英] Haskell lightweight threads overhead and use on multicores

查看:239
本文介绍了Haskell轻量级线程开销和在多核上使用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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




  • 由于Haskell线程真的只是一个真正的OS线程,这是否意味着创建很多(如1000)不会对性能产生严重影响?也就是说,我们可以说用 forkIO 创建一个Haskell线程所产生的开销是(几乎)可以忽略的?


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



解决方案

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



具体来说:


这意味着创建了很多将不会对性能产生剧烈的影响?


好吧,创建1,000,000个肯定是可能的。 1000是如此便宜,甚至不会出现。您可以在线程创建基准中看到,例如 GHC的线程环是非常非常好的


轻量级线程的概念不会阻止我们使用多核架构的优点吗?


不是。自2004年以来, GHC已在多核上运行。多核运行时的当前状态是在此处跟踪



它是如何做到的?阅读此架构的最佳地点在本文中,运行时支持for Multicore Haskell


GHC运行时系统通过将它们复用到少数几个的操作系统线程,
大致为每个物理CPU一个。 ...



Haskell线程由一组操作系统
线程执行,我们称之为工作线程。我们为每个物理CPU保持大约一个
的工作线程,但是确切地说,哪个工作线程
可能会在不同时刻变化...



线程可能改变,我们为每个CPU保持一个
Haskell执行上下文(HEC)。 HEC是一个
数据结构,包含操作系统工作线程
执行Haskell线程所需的所有数据


您可以监控正在创建的主题以及正在执行的主题,通过threadscope。这里,例如。运行binary-trees基准:




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?

解决方案

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.

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:

这篇关于Haskell轻量级线程开销和在多核上使用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆