這是我的理解,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. 爲什麼在linux中爲每個進程保留一個內核堆棧?
- 3. 每個線程都有自己的堆棧嗎?
- 4. 爲什麼每個應用程序都有一個JVM?
- 5. 爲什麼堆棧有界?
- 6. 爲什麼棧,堆的虛擬地址每次都改變?
- 7. 線程堆棧和進程堆棧有什麼區別
- 8. 堆棧爲空...爲什麼?
- 9. 爲什麼這個堆棧粉碎?
- 10. 堆棧旁邊有什麼線程
- 11. 每個進程有多個堆棧?
- 12. Java(JVM)如何爲每個線程分配堆棧
- 13. 兩個進程具有相同的堆棧指針。爲什麼?
- 14. 爲什麼每個表都必須有一個主鍵?
- 15. 每個進程都有自己的內核堆棧,對吧?
- 16. 爲什麼使用兩個堆棧來創建一個隊列?
- 17. 爲什麼堆棧和堆都需要內存分配
- 18. 打印一個進程的所有線程的線程堆棧
- 19. 每個線程或每個方法的堆棧調用?
- 20. 爲什麼堆棧溢出?
- 21. 爲什麼堆棧炸燬
- 22. 爲什麼。每個這裏都不行?
- 23. 爲什麼堆棧大小有限制?
- 24. 爲什麼堆棧沒有推動?
- 25. Xss爲1個線程設置線程堆棧大小,對於所有線程的堆棧大小有什麼限制
- 26. 使用堆棧ghc作爲ghc的替換
- 27. 這個程序爲什麼產生堆棧溢出錯誤?
- 28. 爲什麼一個線程會中斷另一個線程
- 29. 爲什麼每個JDK都帶有3個JRE?
- 30. 爲什麼要減小Java JVM線程堆棧的大小?
您在回答「ghc管理線程如何?」方面做得很好,但問題明確提出「爲什麼?」。我認爲這是與性能有關,但你是否願意詳細說明。 –
它始終是性能 - GHC的執行模型試圖最小化線程對共享對象的爭用(以利用純度)。由於運行時需要堆棧,因此每個線程堆棧是一個明顯的步驟。 –