簡體   English   中英

Haskell中的半顯式並行性

[英]Semi-explicit parallelism in Haskell

我在Haskell中閱讀半顯式並行性,並得到一些混淆。

par :: a -> b -> b

人們說這種方法允許我們通過並行評估Haskell程序的每個子表達式來自動進行並行化。 但這種方法有以下缺點:

1)它創造了太多的小項目,無法有效安排。 據我所知,如果你對Haskell程序的每一行使用par函數,它將創建太多線程,並且它根本不實用。 那正確嗎?

2)使用這種方法,並行性受到源程序中數據依賴性的限制。 如果我理解正確,這意味着每個子表達式必須是獨立的。 就像在par函數中一樣,a和b必須是獨立的。

3)Haskell運行時系統不一定創建一個線程來計算表達式a的值。 相反,它會創建一個spark,它有可能在與父線程不同的線程上執行。

所以,我的問題是:最后運行時系統會創建一個線程來計算或不計算? 或者,如果需要表達式a來計算表達式b,系統將創建一個新線程來計算? 否則,它不會。 這是真的?

我是Haskell的新手,所以也許我的問題對你們所有人來說都是基本的。 感謝您的回答。

你提到的par組合器是格拉斯哥並行Haskell (GpH)的一部分,它實現了半顯式並行性,但這意味着它不是完​​全隱含的,因此不提供自動並行化。 程序員仍然需要識別被認為值得並行執行的子表達式,以避免在1)中提到的問題。

此外,注釋不是規定性的(例如,C中的pthread_create或Haskell中的forkIO),但是建議,這意味着運行時系統最終決定是否並行評估子表達式。 這提供了額外的靈活性和動態粒度控制的方法。 此外,所謂的評估策略已經被設計為抽象超過parpseq並且將協調的規范與計算分開。 例如,策略parListChunk允許對列表進行分塊並將其強制為弱頭正常形式(這是需要一些嚴格性的情況)。

2)並行性受到數據依賴性的限制,在這種意義上,計算定義了圖形減少的方式以及在哪個點上需要哪種計算。 每個子表達式都必須是獨立的,這是不正確的。 例如E1 E2 E2返回E2的結果,這意味着有用,E1的某些部分需要在E2中使用,因此E2依賴於E1。

3)由於GHC特定的術語,這里的圖片略有混淆。 有能力(或Haskell執行上下文)實現並行圖減少並維護火花池和線程池。 通常每個核心有一個能力(可以被認為是OS線程)。 在連續體的另一端有火花,它們基本上是指向尚未評估的圖形部分的指針(thunk)。 並且存在線程(實際上是某種任務或工作單元),因此要並行評估需要將一個spark變成一個線程(它有一個所謂的線程狀態對象,它包含必要的執行環境並允許thunk到並行評估)。 在這些結果到來之前,thunk可能依賴於其他thunk和block的結果。 這些線程比OS線程更輕量級,並且被多路復用到可用的Capablities上。

因此,總而言之,運行時甚至不會創建一個輕量級線程來評估子表達式。 順便說一句,隨機工作竊取用於負載平衡。

這是一種非常高級的並行方法,可以通過設計避免競爭條件和死鎖。 同步是通過圖形縮減隱式調解的。 一個不錯的立場聲明進一步討論了為什么並行功能編程很重 有關幕后抽象機器的更多信息,請查看Stackless Tagless G-Machine並查看GHC wiki上Haskell執行模型的注釋(通常是源代碼旁邊的最新文檔)。

  1. 是的,你是對的。 你不會通過為你想要計算的每個表達式創建一個火花來獲得任何東西。 你會得到方式,太多的火花。 試圖管理這就是Data Parallel Haskell的意義所在。 DPH是一種將嵌套計算分解為大小合適的塊的方法,然后可以並行計算。 請記住,這仍然是一項研究工作,可能還沒有為主流消費做好准備。

  2. 再一次,你是對的。 如果a取決於b,則必須計算b需要能夠開始計算b的多少。

  3. 對。 與某些替代方案相比,線程實際上具有相當高的開銷。 火花有點像thunks只有它們可以獨立於時間計算。

不,RTS不會創建計算a的線程。 您可以決定RTS應該運行多少個線程(六個線程為+RTS -N6 ),並且它們將在程序期間保持活動狀態。

par只會產生火花。 火花不是一個線程。 火花占據工作池,調度程序執行工作竊取 - 即當線程空閑時,它從池中獲取火花並計算它。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM