Perl 6中的"种族"何时值得?

jjm*_*elo 10 concurrency perl6 raku

race将iterable上的操作自动划分为线程.例如,

(Bool.roll xx 2000).race.sum
Run Code Online (Sandbox Code Playgroud)

会自动将2000长阵列的总和分成4个线程.但是,基准测试显示,这比race没有使用时要慢得多.即使您使阵列更大,也会发生这种情况.即使非自动编程版本随每个版本变得越来越快,也会发生这种情况.(自动线程也变得更快,但仍然是不使用它的两倍.)

所以问题是:值得使用的原子操作的最小大小是多少?添加到顺序操作的开销是固定的还是可以某种方式降低?

更新:实际上,性能hyper(类似于种族,但有保证的有序结果)似乎随着时间的推移而变得越来越差,至少对于小尺寸而言,它们仍然是默认批量大小的整数倍(64).同样的情况与race

Eli*_*sen 11

简短的回答:.sum不够聪明,无法分批计算金额.

那么你在这个基准测试中有效地做的是设置一个HyperSeq/ RaceSeq但不做任何并行处理:

dd (Bool.roll xx 2000).race;
# RaceSeq.new(configuration => HyperConfiguration.new(batch => 64, degree => 4))
Run Code Online (Sandbox Code Playgroud)

所以你一直在测量.hyper/ .race开销.你看,在那一刻,只有.map.grep已上实现HyperSeq/ RaceSeq.如果你给点事做,比如:

# find the 1000th prime number in a single thread
$ time perl6 -e 'say (^Inf).grep( *.is-prime ).skip(999).head'
real    0m1.731s
user    0m1.780s
sys     0m0.043s

# find the 1000th prime number concurrently
$ time perl6 -e 'say (^Inf).hyper.grep( *.is-prime ).skip(999).head'
real    0m0.809s
user    0m2.048s
sys     0m0.060s
Run Code Online (Sandbox Code Playgroud)

如您所见,在这个(小)示例中,并发版本的速度是非并发版本的2倍.但使用更多的CPU.

由于.hyper.race得到了正常工作,性能略有改善,你可以看到在这个图.

其他功能,例如.sum可以为.hyper/ 实现.race.但是,我暂时不会这样做,因为我们需要一个小型的重构方式,.hyper而且.race:目前,一批产品无法与"主管"沟通,它完成工作的速度有多快.如果我们想要允许它调整批量大小,如果它发现默认批量大小太小而且我们有太多开销,那么主管需要该信息.

  • 这样一些合理的功能会更好吗?对于任何类似的函数,例如`.min`,会出现这种情况吗? (3认同)
  • @jjmerelo`sum`是一个明智的函数,忽略它必须在返回它之前完成它的所有工作,因此`.hyper`和`.race之间永远不会有任何普通的有用的功能区别. `.(对于`.min`也是如此.)lizmat的观点是"只有`.map`和`.grep`已在`HyperSeq` /`RaceSeq`"上实现,而"其他函数,如`. sum`可以实现`.hyper` /`.race`.但是,我现在会推迟". (3认同)