为什么GHC每个线程都有一个堆栈?

时间:2011-06-22 07:08:01

标签: haskell ghc

我的理解是GHC为每个线程提供堆栈。为什么这有必要? GHC不编译到CPS吗?这个线程不是简洁地表达为闭包吗?

1 个答案:

答案 0 :(得分:5)

您的问题有几个方面。

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

回想一下

  

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

  

每个Haskell线程在一个有限大小的堆栈上运行,该堆栈被分配   堆。线程的状态及其堆栈保存在a中   堆分配的线程状态对象(TSO)。 TSO的大小就在附近   15个字加上堆栈,构成了Haskell的整个状态   线。通过将TSO复制到更大的区域,可以增加堆栈   随后可能会再次缩小

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

一个线程不仅仅是一个闭包。

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

  

线程的堆栈,因此它的TSO是可变的。当一个   线程执行,堆栈将累积指向新对象的指针,   因此,如果TSO位于旧一代,则必须将其添加到   记得的[GC]集。

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

  

此外,当垃圾收集器运行时,   非常希望已经执行的TSO   给定的CPU由同一CPU上的垃圾收集器遍历,   因为它所引用的TSO和数据很可能在本地   该CPU的缓存。

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