私は Perl で実装されたプロジェクトに取り組んでおり、スレッドを使用して作業を分散することを考えました。タスクは互いに独立して実行でき、メモリ内の共有データからのみ読み取ることができるからです。しかし、パフォーマンスは私が期待するほどではありません。そのため、いくつかの調査の結果、Perl のスレッドは基本的に問題があると結論付けることができますが、単一の共有変数を実装するとすぐにパフォーマンスが低下するのではないかと考え続けています。
たとえば、この小さなプログラムは何も共有されておらず、CPU の 75% を消費します (予想どおり)。
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 を使用しています。残念ながら、Windows 以外のマシンで (できれば) 最新の Perl を使用してこれをテストすることはできませんでした。