2011-06-22 52 views

回答

5

你的问题有几个方面。

GHC运行环境中设计决策的关键参考文件是''Runtime Support for Multicore Haskell''

回想

的GHC运行时系统支持数以百万计的轻量线程 的通过复用它们到少数的操作系统线程, 大致一个用于每个物理CPU。

和:

每个的Haskell线程运行上的无限大小的堆栈,它在 堆中分配。线程的状态及其堆栈保存在堆分配线程状态对象(TSO) 中。一个TSO的大小大约是 加上堆栈的15个字,并构成一个Haskell线程的整个状态。堆栈可以通过将TSO复制到更大的区域而增长,并且随后可以再次收缩

GHC不通过CPS进行编译。每个线程都进行递归调用,并且它们必须分配给堆栈。通过将堆栈表示为堆分配对象,事情变得更简单。

线程不仅仅是一个闭包。

当线程执行时,它开始分配给堆和堆栈。因此:

线程的堆栈,因此它的TSO是可变的。当一个 线程执行时,堆栈将累积指向新对象的指针,即 ,所以如果TSO驻留在旧代中,则必须将其添加到记录的[GC]集合的 。

堆栈指向的垃圾收集对象可以进行优化,以确保GC在与线程相同的物理线程上发生。

此外,垃圾收集器运行时, 它是高度期望的是已被一个 给定的CPU上执行的TSOS由相同的CPU上的垃圾收集器穿过, 因为TSO和数据是指可能位于该CPU的本地缓存中。

因此,GHC为每个线程都有一个堆栈,因为编译要求线程可以访问堆栈和堆。通过为每个线程提供自己的堆栈,线程可以更高效地并行执行。线程不仅仅是“封闭”,因为它们有一个可变的堆栈。

+0

您在回答“ghc管理线程如何?”方面做得很好,但问题明确提出“为什么?”。我认为这是与性能有关,但你是否愿意详细说明。 –

+0

它始终是性能 - GHC的执行模型试图最小化线程对共享对象的争用(以利用纯度)。由于运行时需要堆栈,因此每个线程堆栈是一个明显的步骤。 –