저는 Perl로 구현 된 프로젝트에서 작업 중이며 스레드를 사용하여 작업을 분산시키는 것이 좋을 것이라고 생각했습니다. 작업이 서로 독립적으로 수행 될 수 있고 독서 만 가능하기 때문입니다 메모리의 공유 데이터에서 그러나 성능은 내가 예상 한대로 아무데도 없습니다. 그래서 약간의 조사가 끝나면 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을 사용하고 있습니다. 불행히도 필자는 (희망적으로) 최근의 Perl을 사용하여 Windows가 아닌 머신에서 이것을 테스트 할 수 없었다.
잠금이 수행됩니다. 각 쓰레드는 다른 쓰레드가'$ a'를 동시에 읽으려고하는지 알지 못하기 때문에 구현은'$ a'를 읽어 들여야 만합니다. 본질적으로 테스트 코드는 잠금 장치 주위의 단단한 루프입니다. –
하지만'$ a'가 수정되지 않았다는 것을 알고 있습니다. 잠금이 필요 없다는 힌트를 추가 할 방법이 없습니까? –
'$ a' 공유를 표시하지 마십시오. 변수'shared'를 표시하는 것은 특히 변경 사항이 스레드간에 동기화되어야 함을 나타냅니다. 더 좋은 것은'$ b'라는 변수를 공유하지 않고'$ a = $ b; '라는 변수를 만들고 각 스레드가'$ b'를 올바른 값으로 설정하는 것입니다. 그렇게하면 각 스레드는 공유 변수를 한 번만 읽습니다. –