在haskell中,假設我有以下形式的函數調用:foo a b
,其中a
不依賴於b
,反之亦然。似乎可以自動檢測到a
和b
可以並行進行評估,但GHC似乎並不這樣。相反,像par
這樣的結構需要用來表示可以並行評估的東西。Haskell中的自動並行性
那麼,爲什麼haskell中的並行化不能自動發生?或者如果它已經這樣做,爲什麼像par
這樣的結構存在?
在haskell中,假設我有以下形式的函數調用:foo a b
,其中a
不依賴於b
,反之亦然。似乎可以自動檢測到a
和b
可以並行進行評估,但GHC似乎並不這樣。相反,像par
這樣的結構需要用來表示可以並行評估的東西。Haskell中的自動並行性
那麼,爲什麼haskell中的並行化不能自動發生?或者如果它已經這樣做,爲什麼像par
這樣的結構存在?
看來,它可能
並行可以自動爲你暗示通過觀察值之間的依賴關係進行檢測,自動檢測A和B可以並行
進行評估。當沒有副作用時,這特別容易。問題是,知道何時停止並行處理。這一切歸結爲在編譯時知道運行時會發生多少工作。對於任意代碼來說,這些「成本模型」通常很難做到。
考慮:
(+)
並行計算?如果我們天真地並行化所有獨立的計算,編譯器將生成大量的並行任務。數百萬或數十億的並行表達式。我們的8或16核心機器尚未準備好處理。
天真的並行化導致大量開銷嘗試將工作調度到少量可用的並行硬件上。
純程序中的並行性和可用硬件之間的差距迫使我們做出一些妥協。即:其中
第一種形式的示例 - 用戶提示 - are par
annotations或Par
monad。 第二個 - 自動並行子語言 - 請參閱Data Parallel Haskell。
這個答案*假設*(a)有一個非常天真的運行時環境,盲目地產生任務和/或(b)在編譯時必須知道必須在何處引入多少並行性。它沒有指出自動並行(在Haskell中)只是一個未解決的問題,而不是一個無法解決的問題。 (a)爲什麼不能例如(固定池)工作線程根據現有線程的運行時棧確定自己在哪裏可以去做什麼工作? (b)爲什麼必須在編譯時知道並行化必須發生? – masterxilo 2017-04-13 00:10:06
我不明白爲什麼我們不能在C/C++中編寫一個Haskell風格的函數(無副作用和無狀態)程序,並使用例如[Cilk](https://en.wikipedia.org/wiki/Cilk)在每個子函數調用(「foo ab」示例中的'a'和'b')上盲目地使用'spawn'和'sync'關鍵字),然後在計算結果中的'foo a'b'之前執行'sync'。關鍵字僅僅是提示,如果所有工作線程都已佔線,運行時將忽略它們。看起來像理想的解決方案... – masterxilo 2017-04-13 00:14:50
自動並行性的問題是它增加了開銷,並且很難自動確定兩個表達式的並行評估是否帶來好處。 – 2014-09-28 11:59:08
另請參閱[Data Parallel Haskell](http://www.haskell.org/haskellwiki/GHC/Data_Parallel_Haskell)。 – 2014-09-28 12:00:18
@PetrPudlák所以問題不是那麼多,原理不起作用,但它沒有那麼大的收益,甚至可能變得更慢? – Kritzefitz 2014-09-28 12:12:07