2010-09-09 84 views
11

更新:我剛剛發現this documentation page。希望有一個從the documentation that I'd been using鏈接到它,它似乎是權威的API文檔。但也許這是一個新的,未發佈的工作。如何在Haskell Control.Parallel.Strategies中制定策略?

更新2:本文檔爲我提供了一個更好的主意,即如何使用Control.Parallel.Strategies模塊。不過,我還沒有完全解決這個問題......看問題的結尾。

我一直在嘗試在Haskell中使用parListChunk或其他一些並行控制功能。但我無法弄清楚如何使用它們。警告:我是Haskell noob。大約20年前我學習了一些關於函數式編程的知識(!)。

這裏是我的非並行功能:

possibKs n r = [ (k, (hanoiRCountK n k r)) | k <- [1 .. n-1] ] 

我想並行化,像這樣幼稚的嘗試:

possibKs n r 
    | n < parCutoff = results 
    | otherwise  = parListChunk parChunkSize results 
    where results = [ (k, (hanoiRCountK n k r)) | k <- [1 .. n-1] ] 

但該結構是不適合parListChunk。 文檔說:

parListChunk :: Int -> Strategy a -> Strategy [a] 

parListChunk sequentially applies a strategy to chunks (sub-sequences) of a list in parallel. Useful to increase grain size

好,這就是我想要的。但如何使用它?我一直無法找到任何這樣的例子。如果我理解類型聲明,parListChunk是一個函數,它需要一個Int和一個Strategy<a>(借用C++參數化符號來幫助檢查我是否真的理解這個權利),並返回Strategy<[a]>。在我的情況下,我正在處理Inta所以parListChunk將需要Int參數和Strategy<Int>。那麼什麼是Strategy,我該如何製作一個?一旦我成功使用了parListChunk,我該如何處理它所吐出的Strategy

Strategy type is defined這樣的:

type Strategy a = a -> Done 

(這是所有的戰略文件) 所以一個Strategy<Int>是一個函數,完成int類型返回的參數。顯然它會導致它的論證在某個時間或某個時間得到評估。我在哪裏得到一個,我應該使用什麼樣的?

以下功能似乎回報策略:

sPar :: a -> Strategy b 
sSeq :: a -> Strategy b 
r0 :: Strategy a 
rwhnf :: Strategy a 

但他們都不讓你決定使用哪種類型的參數 - 它們產生Strategy<b>當你給參數a,否則你沒有得到供應參數a!那是怎麼回事??除此之外,我不知道這是什麼意思。

我做了SO找到類似的功能parList being used的一個例子:

return . maximum $ map optimize xs `using` parList 

它使用這個時髦using功能,它宣稱:

using :: a -> Strategy a -> a 

不夠公平......在我的情況我可能想要a[Int],所以它需要一個Ints列表和一個Strategy<[Int]>和(做些什麼?將策略應用於列表?並且)返回一個Ints列表。於是,我就跟着parList例子,改變了我的otherwise後衛:

| otherwise  = results `using` parListChunk parChunkSize 

但我必須承認,我仍然在黑暗中拍攝......我不能完全跟隨周邊類型簽名。所以,這不是太奇怪,上面給出了一個錯誤:

Couldn't match expected type `[(Int, Integer)]' 
     against inferred type `a -> Eval a' 
Probable cause: `parListChunk' is applied to too few arguments 
In the second argument of `using', namely 
    `parListChunk parChunkSize' 
In the expression: results `using` parListChunk parChunkSize 

誰能告訴我用什麼爲Strategy a參數parListChunk?以及如何使用由parListChunk返回的Strategy [a]

新建部分

看着Basic Strategies,我想我需要使用rseq策略。大概。所以我嘗試

| otherwise  = results `using` (parListChunk parChunkSize rseq) 

但GHC說rseq是「不在範圍內」。 These API docs表示包中沒有rseq,但sSeq似乎已將其替換。好的,所以我使用了sSeq,但它「不在範圍內」。即使我正在導入Control.Parallel.Strategies

任何線索?順便說一句我用來獲取有關加載包這些消息:

Loading package deepseq-1.1.0.0 ... linking ... done. 
Loading package parallel-2.2.0.1 ... linking ... done. 

因此很明顯,告訴我有什麼版的水貨包裝:2.2.0.1。但是我在API docs中看不到有關此處描述的版本的信息。如果我不應該使用rseq或sSeq,我應該使用什麼? Edward怎麼能夠使用parList?

回答

2

好的,我得到的代碼工作。我把它用rwhnf,而不是rseq編譯:

| otherwise  = results `using` (parListChunk parChunkSize rwhnf) 

this source coderwhnf在第3版改名爲rseq所以我想我的並行包的版本已經過時了相對於this documentation。 :-S

我想這是使用「實驗」包的價格的一部分。

無論如何,代碼編譯和運行。是否它對並行性有用是另一個問題...

+2

確保您使用+ RTS -N運行可執行文件以使用多個內核。如果啓用+ RTS -s來顯示統計信息,則可以看到跨核心傳輸工作的效率。爲了更細緻的調優,請使用ThreadScope(http://research.microsoft.com/en-us/projects/threadscope/)。 – 2010-09-09 22:07:02

+0

謝謝,@約翰。在WinGCHi中,我在GHCi啓動選項中有「ghc --interactive-threaded」。我想這還不夠?我可以在WinGCHi內運行多線程程序嗎? – LarsH 2010-09-09 22:13:50

+0

IIRC ghci總是使用線程運行時(例如-threaded是隱式的)。只需在啓動選項中指定你想要的運行時選項,你應該沒問題。如果您不使用-N,則默認情況下即使使用線程運行時也要保留在一個內核上。 – 2010-09-09 23:23:18