Lar*_*rsH 11 parallel-processing haskell
更新:我刚刚找到了这个文档页面.希望从我一直使用的文档中找到它的链接,这似乎是最终的API文档.但也许这是一个新的未发布的作品.
更新2:本文档让我更好地了解了如何使用Control.Parallel.Strategies模块.但是我还没有完全解决问题......看到问题的结尾.
我一直在尝试在Haskell中使用parListChunk或其他一些并行控制功能.但我无法弄清楚如何使用它们.警告:我是Haskell noob.大约20年前,我学习了一些关于函数式编程的东西(!).
这是我的非并行功能:
possibKs n r = [ (k, (hanoiRCountK n k r)) | k <- [1 .. n-1] ]
Run Code Online (Sandbox Code Playgroud)
我希望将它并行化,就像这种天真的尝试:
possibKs n r
| n < parCutoff = results
| otherwise = parListChunk parChunkSize results
where results = [ (k, (hanoiRCountK n k r)) | k <- [1 .. n-1] ]
Run Code Online (Sandbox Code Playgroud)
但是这个结构不适合parListChunk.文档说:
parListChunk :: Int -> Strategy a -> Strategy [a]
Run Code Online (Sandbox Code Playgroud)
parListChunk顺序地将策略应用于列表的块(子序列).有用增加粒度
好,这就是我想要的.但是怎么用呢?我还没有找到任何这方面的例子.如果我理解类型声明,parListChunk是一个带a Int
和a 的函数Strategy<a>
(借用C++参数化类型表示法来帮助检查我是否真的理解这一点),并返回一个Strategy<[a]>
.在我的情况下我正在处理Int
因为a
parListChunk将需要一个Int
参数和一个Strategy<Int>
.那是Strategy
什么,我如何生产一个?一旦我成功使用了parListChunk,我该怎么做Strategy
才吐出来?
该策略类型定义是这样的:
type Strategy a = a -> Done
Run Code Online (Sandbox Code Playgroud)
(这就是Strategy的所有文档.)所以a Strategy<Int>
是一个函数,它接受Int类型的参数并返回Done.显然它会导致其论证在某个时间或某个时间得到评估.我从哪里得到一个,我应该使用哪种?
以下函数似乎返回策略:
sPar :: a -> Strategy b
sSeq :: a -> Strategy b
r0 :: Strategy a
rwhnf :: Strategy a
Run Code Online (Sandbox Code Playgroud)
但是它们都没有让你确定类型参数 - 它们Strategy<b>
在你给出参数时会产生一个参数a
,否则你就无法提供参数a
!那是怎么回事??除此之外,我不知道这些意味着什么.
我确实找到了在SO 上使用的类似函数parList的一个例子:
return . maximum $ map optimize xs `using` parList
Run Code Online (Sandbox Code Playgroud)
它使用这个时髦的using
函数,声明:
using :: a -> Strategy a -> a
Run Code Online (Sandbox Code Playgroud)
很公平......在我的情况下我可能想a
成为[Int]
,所以它需要一个Ints列表和一个Strategy<[Int]>
和(确实有什么?将策略应用到列表中?)并返回一个Ints列表.所以我尝试按照parList示例将我的otherwise
后卫改为:
| otherwise = results `using` parListChunk parChunkSize
Run Code Online (Sandbox Code Playgroud)
但我必须承认我还在黑暗中拍摄......我不能完全遵循周围的类型签名.所以上面给出错误并不太令人惊讶:
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
Run Code Online (Sandbox Code Playgroud)
有人能告诉我Strategy a
parListChunk 的参数用什么吗?以及如何使用Strategy [a]
parListChunk返回的?
新的一部分
看看基本策略,我想我需要使用这个rseq
策略.大概.所以我试试
| otherwise = results `using` (parListChunk parChunkSize rseq)
Run Code Online (Sandbox Code Playgroud)
但GHC表示rseq"不在范围内".
这些API文档说包中没有rseq,但sSeq似乎已经取代了它.好的,所以我使用了sSeq,但它也"不在范围内".即使我正在进口Control.Parallel.Strategies
.
有线索吗?顺便说一句,我以前收到有关加载包的消息:
Loading package deepseq-1.1.0.0 ... linking ... done.
Loading package parallel-2.2.0.1 ... linking ... done.
Run Code Online (Sandbox Code Playgroud)
显然,这告诉我有哪个版本的并行软件包:2.2.0.1.但我没有在API文档中看到有关那里描述的版本的信息.如果我不使用rseq或sSeq,我应该使用什么?爱德华怎么能够使用parList?
好的,我让代码工作了。rwhnf
我通过使用而不是编译它rseq
:
| otherwise = results `using` (parListChunk parChunkSize rwhnf)
Run Code Online (Sandbox Code Playgroud)
根据这个源代码,在版本 3 中rwhnf
被重命名为。rseq
所以我想我的并行包版本相对于这个文档来说已经过时了。:-S
我想这是使用“实验”包的价格的一部分。
无论如何,代码会编译并运行。它是否对并行性做任何有用的事情是另一个问题......