gpt4 book ai didi

haskell - 如何结合 `` parBuffer `` and ` `parListChunk`` 的优点?

转载 作者:行者123 更新时间:2023-12-04 17:58:36 26 4
gpt4 key购买 nike

我有一些 Haskell 代码,它涉及对一个大的(65.5k 元素)项目列表做很多相互不重叠的事情。这似乎非常适合并行化,我使用 Control.Parallel.Strategies.parBuffer 进行了并行化。这有所帮助,但我确信这项工作过于细化,而且我还想分块处理列表(正如 Control.Parallel.Strategies.parListChunk 所做的那样)。然而,因为我的列表很大,使用 only parListChunk 的实验并没有获得那么多的加速,因为必须评估整个 65-odd-thousand-item 列表才能使这项工作(如程序的内存使用所示)。

有没有一种方法可以编写一个Strategy,让我受益于both parBuffer(即列表被视为惰性缓冲区具有可控数量的评估)以及 parListChunk(即,工作被分解成由列表的几个元素组成的部分,而不是单个元素)。我不太确定该怎么做。

编辑:根据要求,这是我正在处理的内容,并附有解释性评论:

parBufferMap :: Int -> Strategy b -> (a -> b) -> [a] -> [b]
parBufferMap i strat f = withStrategy (parBuffer i strat) . fmap f

main :: IO ()
main = do
let allTables = genAllTables 4 -- a list of 65.5k Tables
let results = parBufferMap 512 rdeepseq theNeedful allTables -- theNeedful is what I need to do to each Table, independently of each other
let indexed = zip [1..] results
let stringified = stringify <$> indexed -- make them pretty for output
void . traverse putStrLn $ stringified -- actually print them

我的目标是将 results 计算原样(使用 only parBufferMap)替换为结合了 优点的东西parBufferMapparListChunk

最佳答案

看来你想计算:

map theNeedful allTables

但是你想批量映射 512 个表。

这看起来对你有用吗?

-- assuming:
theNeedful :: Table -> Result

nthreads = 4 -- number of threads to keep busy
allTables = ...
allBatches = chunksOf 512 allTables -- from Data.List.Split

doBatch :: [Table] -> [Result]
doBatch tables = map theNeedful tables

results :: [Result]
results = concat $ withStrategy (parBuffer nthreads rdeepseq) (map doBatch allBatches)
...

言外之意:

  1. 将表格分成 512 个表格的 block
  2. doBatch 映射到所有批处理上
  3. 对该计算列表执行parBuffer
  4. concat 结果列表

关于haskell - 如何结合 `` parBuffer `` and ` `parListChunk`` 的优点?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38175725/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com