gpt4 book ai didi

Haskell 嵌套向量并行策略

转载 作者:行者123 更新时间:2023-12-02 17:03:40 26 4
gpt4 key购买 nike

类似于this related question ,我想在向量上执行并行映射,但在我的例子中,我有一个嵌套向量,并且我似乎无法获得正确的评估。

这是我到目前为止所拥有的:

import qualified Data.Vector as V
import qualified Data.Vector.Unboxed as U
import Data.Vector.Strategies
import Control.DeepSeq

main = do
let res = genVVec 200 `using` parVector 2
print res

genUVec :: Int -> U.Vector Int
genUVec n = U.map (ack 2) $ U.enumFromN n 75

genVVec :: Int -> V.Vector (U.Vector Int)
genVVec n = V.map genUVec $ V.enumFromN 0 n

ack :: Int -> Int -> Int
ack 0 n = n+1
ack m 0 = ack (m-1) 1
ack m n = ack (m-1) (ack m (n-1))

instance (NFData a, U.Unbox a) => NFData (U.Vector a) where
rnf = rnf . U.toList

给出:

$ ./vectorPar +RTS -N8 -s >/dev/null
SPARKS: 200 (17 converted, 183 pruned)
Total time 1.37s ( 1.30s elapsed)
$ ./vectorPar +RTS -s >/dev/null
SPARKS: 200 (0 converted, 200 pruned)
Total time 1.25s ( 1.26s elapsed)

我还尝试修改 parVector 函数 in vector-strategies直接,但我的尝试是笨拙且无效的。

我意识到 REPA 是为嵌套工作负载而设计的,但这似乎是一个足够简单的问题,我宁愿不必重写大量代码。

最佳答案

注意:这里是矢量策略的有罪作者(这是一个非常小的标题,因为这只是一个我认为其他人会发现有用的黑客功能)。

您认为 parVector 是错误的,因为它允许在使用之前对 Spark 进行 GC 处理,这似乎是正确的。 SimonM 的建议意味着我必须精确地做我试图避免的事情,以一定的成本构建一个新的向量来代替旧的向量。知道这是必要的,没有理由不将 parVector 更改为更简单的定义:

parVector2 :: NFData a => Int -> Strategy (V.Vector a)
parVector2 n = liftM V.fromList . parListChunk n rdeepseq . V.toList

请注意,John L 给出的修复之所以有效,是因为它通过在收集发生之前强制进行计算来“击败”收集器。

我将更改矢量策略库,因此这是不必要的 - 使您的原始代码正常工作。不幸的是,这将产生上述构建新 Vector 的成本(通常很小)。

关于Haskell 嵌套向量并行策略,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6750297/

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