我正在开发一个用 Perl 实现的项目,并认为使用线程来分配工作是一个不错的主意,因为这些任务可以相互独立地完成,并且只能从内存中的共享数据中读取。但是,性能与我预期的相差甚远。因此,经过一番调查,我只能得出结论,Perl 中的线程基本上很烂,但我一直想知道,一旦我实现了一个共享变量,性能就会下降。
例如,这个小程序没有共享任何东西,并且消耗了 75% 的 CPU(如预期的那样):
use threads;
sub fib {
my ( $n ) = @_;
if ( $n < 2 ) {
return $n;
} else {
return fib( $n - 1 ) + fib( $n - 2 );
}
}
my $thr1 = threads->create( 'fib', 35 );
my $thr2 = threads->create( 'fib', 35 );
my $thr3 = threads->create( 'fib', 35 );
$thr1->join;
$thr2->join;
$thr3->join;
一旦我引入一个共享变量$a
,CPU 使用率就在 40% 到 50% 之间:
use threads;
use threads::shared;
my $a : shared;
$a = 1000;
sub fib {
my ( $n ) = @_;
if ( $n < 2 ) {
return $n;
} else {
return $a + fib( $n - 1 ) + fib( $n - 2 ); # <-- $a was added here
}
}
my $thr1 = threads->create( 'fib', 35 );
my $thr2 = threads->create( 'fib', 35 );
my $thr3 = threads->create( 'fib', 35 );
$thr1->join;
$thr2->join;
$thr3->join;
$a
只读也是如此,不会发生锁定,但性能会降低。我很好奇为什么会这样。
目前我在 Windows XP 上的 Cygwin 下使用 Perl 5.10.1。不幸的是,我无法在具有(希望)更新的 Perl 的非 Windows 机器上对此进行测试。