race https://docs.perl6.org/routine/race自动将可迭代对象上的操作划分为线程。例如,
(Bool.roll xx 2000).race.sum
会自动将 2000 长数组的总和分成 4 个线程。然而,基准测试显示 https://gist.github.com/Whateverable/50fbba42544f1472543aa997f91a4c1d这比 if 慢得多race
没有就业。有时候是这样的即使你让数组更大 https://gist.github.com/Whateverable/57fd99f76f59e1af97db01544a7b8f2c。
即使当每个版本的非自动线程版本变得越来越快 https://gist.github.com/Whateverable/81191278502dc1a352a254b647e28308. (自动线程也变得更快 https://gist.github.com/Whateverable/28dc7965c035258f14585ec8c9cc5a21,但仍然比不使用它慢两倍。)
那么问题是:值得使用的原子操作的最小大小是多少?添加到顺序操作的开销是固定的还是可以以某种方式减少?
Update: 实际上,的表演hyper(类似于比赛,但有保证的有序结果)随着时间的推移似乎变得越来越糟 https://gist.github.com/Whateverable/e09069f58f4712bf2c4b32b3bbf8401b,至少对于小尺寸来说,它们仍然是默认批量大小(64)的整数倍。相同的发生在race https://gist.github.com/Whateverable/319587af276dddbeec2af7cefc2c5aa2
简短的回答:.sum
不够聪明,无法批量计算总和。
所以你在这个基准测试中有效地做的是建立一个HyperSeq
/ RaceSeq
但随后不进行任何并行处理:
dd (Bool.roll xx 2000).race;
# RaceSeq.new(configuration => HyperConfiguration.new(batch => 64, degree => 4))
所以你一直在测量.hyper
/ .race
高架。你看,此刻,只有.map
and .grep
已实施于HyperSeq
/ RaceSeq
。如果你给that要做一些事情,例如:
# 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。
Since .hyper
and .race
可以正常工作,性能略有提高,如您所见在此图中 https://gist.github.com/Whateverable/ee98308dcca3561d46bff8128bc4de20.
其他功能,例如.sum
可以实施为.hyper
/ .race
。然而,我现在会推迟这一点,因为我们需要对我们的工作方式进行一些小的重构.hyper
and .race
:目前,批次无法向“主管”传达其完成工作的速度。如果我们想让主管进行调整,例如,主管需要这些信息。 batch-size,如果它发现默认的batch-size太小并且我们的开销太大。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)