一系列地图/褶皱,其中;“转换层”;在Haskell是并行运行的吗?(“垂直”平行度与“水平”平行度相对。)

一系列地图/褶皱,其中;“转换层”;在Haskell是并行运行的吗?(“垂直”平行度与“水平”平行度相对。),haskell,parallel-processing,stream,pipeline,fold,Haskell,Parallel Processing,Stream,Pipeline,Fold,我所看到的关于并行列表处理的大多数问题都与将列表分块并并行处理每个块所实现的并行性有关 我的问题不同 关于maps和folds的序列,我有一个更简单/更愚蠢的想法:如果我们只想为第一个map设置一个作业,该作业应该与第二个map并行执行,该怎么办 我想到的计算结构是: xs -- initial data ys = y1 : y2 : ... : yn -- y1 = f x1, ... and so on. -- computed in one parallel job. zs = z1

我所看到的关于并行列表处理的大多数问题都与将列表分块并并行处理每个块所实现的并行性有关

我的问题不同

关于
map
s和
fold
s的序列,我有一个更简单/更愚蠢的想法:如果我们只想为第一个
map
设置一个作业,该作业应该与第二个
map
并行执行,该怎么办

我想到的计算结构是:

xs -- initial data

ys = y1 : y2 : ... : yn -- y1 = f x1, ... and so on.
-- computed in one parallel job.

zs = z1 : z2 : ... : zn -- z1 = g y1, ... and so on.
-- computed in another job (the applications of `g`), i.e., the "main" job.
以下代码的精神会起作用吗

ys = map f xs
zs = ys `par` map g' ys
    where g' y = y `pseq` g y
我只需要说,
ys
应该用一种
deepSeq
而不是简单地写:

ys `par` ...
因此,虽然主要工作将忙于计算a
g
,但我们也在强制提前并行计算
ys

这种方法有什么问题吗

关于
par
pseq
的文档和示例对我来说有点缺乏,无法理解这是如何实现的。我的代码与我在一些示例中看到的不同之处在于,
par
pseq
左侧的值在我的代码中是不同的

讨论 我可以为其他类型的转换想到类似的并行化(
fold
scan
,以及更复杂的组合)

首先,我担心
ys
的元素可能会被评估 如果
g
过快,则执行两次

这将提供一个固定的两倍加速与2核心

如果在我的管道中有更多这样昂贵的转换节点(比如,
N
),我会得到固定的
N
倍的加速

至于我的并行化与他们的(、等)水平(通过
parMap
实现):我想获得更快的流式处理。换句话说:我首先希望看到中间结果(增量
initszs
)更快

校正 似乎我不明白pseq的意思。请考虑上面的旧代码:

zs = ys `par` map g' ys
    where g' y = y `pseq` g y
并重新读取
pseq

seq
的两个参数都很严格,因此编译器可能 例如,重新排列

a `seq` b
变成。。。注释的代码时可能会出现问题 并行性,因为我们需要更多地控制 评价我们可能想在
b
之前评估
a
,因为我们知道 该
b
已与
par
并行触发

所以,在我的例子中,
y
是我想用
par
激发和强制的价值的一部分,所以它就像
b
,没有必要/有意义把它放在
pseq
下,对吗

但我仍然有点担心,如果我们在地图上的速度太快,它的计算是否会意外地重复

我也看过了,但是他们谈论了
rpar
rseq
。。。
它们似乎暗示在
rpar/rpar
rpar/rseq/rseq
的情况下,无需额外担心等待值,就可以执行
rpar/rpar
。我做错什么了吗?

为什么不使用一个函子定律,然后做
zs=map(g.f)
(如果你愿意的话,并行地)呢我知道没有答案,只是saying@CarstenK嗯,我认为这是一种并行化的方法,可以获得2倍的加速。使用
map(g.f)
我在一个线程中完成了所有工作。如果
g
f
成本高昂和/或列表庞大,则与直接合成相比,2倍的加速效果必须明显,而列表构建的成本是可以忽略的。好吧-那么你想做一些流媒体/管道/导管之类的事情-对不起,我理解错了-也许你会在管道生态系统中找到一些东西(想到这里)你读过Simon Marlow关于并行和并发Haskell的优秀著作吗?我怀疑这本书不太受欢迎,因为许多/大多数实际应用程序要么由超标量CPU处理,而你几乎没有帮助,要么需要非常专业的硬件才能有效。问题在于,通用硬件上的这种并行性似乎涉及线程之间的大量通信,而且看起来很难平衡。不过,我不是专家。