Concurrency 什么时候是;种族“;在Perl 6中值得吗?

Concurrency 什么时候是;种族“;在Perl 6中值得吗?,concurrency,raku,Concurrency,Raku,将iterable上的操作自动划分为线程。比如说, (Bool.roll xx 2000).race.sum 将自动将2000长数组的总和分成4个线程。然而,这比不使用race要慢得多。这种情况经常发生。 这种情况甚至会随着时间的推移而发生。(,但速度仍然是不使用的两倍。) 所以问题是:值得使用的原子操作的最小规模是多少?顺序操作增加的开销是固定的还是可以以某种方式减少 更新:事实上,至少对于小批量,它们仍然是默认批量大小(64)的整数倍。同样的简单的答案是:.sum不够聪明,无法批量计算总和

将iterable上的操作自动划分为线程。比如说,

(Bool.roll xx 2000).race.sum
将自动将2000长数组的总和分成4个线程。然而,这比不使用
race
要慢得多。这种情况经常发生。 这种情况甚至会随着时间的推移而发生。(,但速度仍然是不使用的两倍。)

所以问题是:值得使用的原子操作的最小规模是多少?顺序操作增加的开销是固定的还是可以以某种方式减少


更新:事实上,至少对于小批量,它们仍然是默认批量大小(64)的整数倍。同样的

简单的答案是:
.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
工作正常,性能略有提高,如您所见


其他功能,如
.sum
可以为
.hyper
/
.race
实现。不过,我暂时暂缓,因为我们需要对
.hyper
.race
的工作方式进行一次小的重构:目前,批处理无法向“主管”反馈其完成工作的速度。如果我们希望允许主管调整,例如批量大小,如果主管发现默认批量太小,并且我们的开销太大,那么主管需要这些信息。

因此,使用一些合理的功能会更好吗?任何类似的函数,如
.min
,都是这样吗?@jmerelo
sum
是一个合理的函数,忽略了它必须在返回一个结果之前完成所有的工作,因此
.hyper
.race
之间永远不会有任何普通有用的可见功能差异。(对于
.min
)lizmat的观点是,“只有
.map
.grep
已经在
HyperSeq
/
RaceSeq
上实现了”,并且“其他功能,如
.sum
可用于
.hyper
/
.race
。不过,我暂时暂且不谈这一点。“原子操作”在编程中有非常具体的含义。它并不意味着“最少的操作/表达式/语句”Hi jj.FYI:1)”
(Bool.roll xx 2000)。race.sum
会自动将2000长数组的和分成4个线程。“它可能会。这取决于编译器是否真的会这样做。2) “自动线程化”已经实现。这并不意味着自动在线程上运行。