这是我的理解,GHC给每个线程一个堆栈。为什么这是必要的? GHC是否编译成CPS?不是一个线程简洁地表达为闭包?为什么GHC为每个线程都有一个堆栈?
6
A
回答
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为每个线程都有一个堆栈,因为编译要求线程可以访问堆栈和堆。通过为每个线程提供自己的堆栈,线程可以更高效地并行执行。线程不仅仅是“封闭”,因为它们有一个可变的堆栈。
相关问题
- 1. C++堆栈/堆栈。为什么只有一个新操作员?
- 2. 为什么堆栈有界?
- 3. 为什么栈,堆的虚拟地址每次都改变?
- 4. 线程堆栈和进程堆栈有什么区别
- 5. 堆栈为空...为什么?
- 6. 为什么会有堆栈和堆?
- 7. 堆栈旁边有什么线程
- 8. Java(JVM)如何为每个线程分配堆栈
- 9. 两个进程具有相同的堆栈指针。为什么?
- 10. 为什么每个表都必须有一个主键?
- 11. 为什么使用两个堆栈来创建一个队列?
- 12. 为什么堆栈和堆都需要内存分配
- 13. 每个线程或每个方法的堆栈调用?
- 14. 打印一个进程的所有线程的线程堆栈
- 15. 为什么堆栈溢出?
- 16. 为什么。每个这里都不行?
- 17. 为什么堆栈没有推动?
- 18. 为什么堆栈大小有限制?
- 19. 使用堆栈ghc作为ghc的替换
- 20. 为什么有两个线程的8个进程每个创建的负载都比一个具有16个线程的进程多?
- 21. 为什么要减小Java JVM线程堆栈的大小?
- 22. 线程堆栈上存储了什么?
- 23. 为什么堆栈结束为空?
- 24. 为什么一个对话似乎有它的一个线程?
- 25. 为什么每次都得到堆栈溢出异常或逻辑错误; java
- 26. 为什么每个进程有一个页表
- 27. 有关线程和进程堆栈的一个简单问题
- 28. 如何升级堆栈GHC
- 29. 为什么我们需要为每个线程使用NSAutoreleasepool?
- 30. luaL_dostring什么都不放在堆栈上?
您在回答“ghc管理线程如何?”方面做得很好,但问题明确提出“为什么?”。我认为这是与性能有关,但你是否愿意详细说明。 –
它始终是性能 - GHC的执行模型试图最小化线程对共享对象的争用(以利用纯度)。由于运行时需要堆栈,因此每个线程堆栈是一个明显的步骤。 –