race
自动将可迭代对象的操作划分为多个线程。例如,
(Bool.roll xx 2000).race.sum
会自动将2000长数组的总和分为4个线程。但是,benchmarks show比没有使用race
的情况要慢得多。 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至少适用于小尺寸,这些尺寸仍然是默认批处理大小(64)的整数倍。相同的happens with race
答案 0 :(得分:11)
简短的答案:.sum
不够聪明,无法批量计算总和。
因此,在此基准测试中,您实际上要做的是设置HyperSeq
/ RaceSeq
,但不进行任何并行处理:
dd (Bool.roll xx 2000).race;
# RaceSeq.new(configuration => HyperConfiguration.new(batch => 64, degree => 4))
因此,您一直在测量.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
如您所见,在这个(小的)示例中,并发版本的速度是非并发版本的2倍以上。但是会使用更多的CPU。
自.hyper
和.race
正常工作以来,性能有了一些改善,如您所见in this graph。
可以为.sum
/ .hyper
实现其他功能,例如.race
。但是,我暂时暂不考虑这一点,因为我们需要对.hyper
和.race
的方式进行少量重构:目前,一批不能与“主管”进行通讯。它完成工作的速度。如果我们想让主管进行调整,例如,主管需要该信息。批处理大小,如果发现默认的批处理大小太小并且我们的开销太大。