"race" 在 Perl 6 中什么时候值得?

When is "race" worthwhile in Perl 6?

race 将可迭代对象上的操作自动划分为线程。例如,

(Bool.roll xx 2000).race.sum

会自动将2000长数组的总和分成4个线程。然而,benchmarks show that this is much slower than if race were not employed. This happens even if you make the array bigger。 即使 non-autothreaded version gets faster and faster with each version. (Auto-threading also gets faster 也会发生这种情况,但仍然比不使用它慢两倍。)

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

更新:其实performance of hyper (similar to race, but with guaranteed ordered results) seems to be getting worse with time, at least for small sizes which are nonetheless integer multiples of the default batch size (64). Same happens with race

简短回答:.sum 不够智能,无法批量计算总和。

所以您在此基准测试中有效地做的是设置 HyperSeq / RaceSeq 但随后不进行任何并行处理:

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

所以您一直在测量 .hyper / .race 开销。你看,目前只有 .map.grepHyperSeq / 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

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

自从 .hyper.race 开始正常工作后,性能略有提高,如您所见 in this graph.

可以为 .hyper / .race 实现其他功能,例如 .sum。但是,目前我会推迟,因为我们需要对 .hyper.race 的方式进行小的重构:目前,批处理无法与 "supervisor" 它完成工作的速度。如果我们想让主管进行调整,例如主管需要该信息。 batch-size,如果它发现默认的batch-size太小,我们的开销太大。