【发布时间】:2019-12-24 16:29:05
【问题描述】:
我正在用 Haskell 编写 rainbow table 的玩具实现。主要数据结构是严格的Map h c,包含大量对,由随机值c生成:
import qualified Data.Map as M
import System.Random
table :: (RandomGen g, Random c) => Int -> g -> Map h c
table n = M.fromList . map (\c -> (chain c, c)) . take n . randoms
chain 的计算成本非常高。支配计算时间的部分是令人尴尬的并行,所以如果并行运行,我希望在内核数量上获得准线性加速。
但是,我希望将计算的对立即添加到表中,而不是累积在内存中的列表中。需要注意的是,可能会发生冲突,在这种情况下,应该尽快丢弃冗余链。堆分析证实了这种情况。
我从Control.Parallel.Strategies 中找到了parMap,并尝试将其应用于我的建表功能:
table n = M.fromList . parMap (evalTuple2 rseq rseq) (\c -> (chain c, c)) . take n . randoms
但是,使用-N 运行时,我最多只能使用 1.3 个核心。堆分析至少表明中间列表不驻留在内存中,但“-s”还报告创建了 0 个火花。我使用 parMap 怎么可能?这样做的正确方法是什么?
编辑:chain 定义为:
chain :: (c -> h) -> [h -> c] -> c -> h
chain h = h . flip (foldl' (flip (.h)))
其中(c -> h)是目标哈希函数,从明文到哈希,
[h -> c] 是减速器函数家族。我希望实现在c 和h 上保持通用,但对于基准测试我对两者都使用严格的字节串。
【问题讨论】:
-
您使用的是哪个版本的
parallel?足够旧的版本存在一些非常严重的问题。 -
@dfeuer parallel-3.2.2.0,很遗憾
-
Hrmmmm.... 你在使用什么
-N参数? -
@dfeuer 我试过 -N4 和 -N8,两者都给出或多或少相同的结果(低于 2 个核心使用)
-
Checkout github.com/lehins/haskell-scheduler 我专门为这样的用例编写了它。
标签: haskell parallel-processing