2009-11-07 13 views
8

A presentation przez Mikhael Goikhman z konferencji Perl z 2003 r. Zawiera parę przykładów skryptów zawierających najlepsze liczby. One jest gwintowany, a other nie jest. Po uruchomieniu skryptów (skomentowałem wypisane linie), uzyskałem czas wykonania 0,011s na nie-gwintowanym i 2,343 (!) Sekundę na wersji gwintowanej. Co powoduje oszałamiającą różnicę w czasie?Dlaczego wątkowa wersja tego konkretnego skryptu Perla jest 200 razy wolniejsza niż jego nie-gwintowany odpowiednik?

Mam pewne doświadczenie z wątkami w Perlu i zauważyłem, że czasy tworzenia wątków mogą być szczególnie brutalne, ale nie wydaje się to być wąskim gardłem w przykładzie Goikhama.

+0

Twoje linki "Jeden" i "inne" są cofnięte. – mob

+0

Naprawiono to teraz; dzięki. –

+0

Prawdopodobnie spędzasz 0,0055 sekundy, znajdując liczby pierwsze teraz, i 2,3375 sekund, sprawiając, że problem może się kręcić. – jrockway

Odpowiedz

11

Jestem facetem Python, Perl nie, więc mają tylko mgliste pojęcie o tym, co robi kod. Zawsze jednak uważaj, gdy widzisz Kolejki. Python ma kolejkę bezpieczną dla wątków i wygląda na to, że Perl też. Są fantastyczne w tym, że dbają o bezpieczeństwo wątków, ale zazwyczaj wymagają one kosztownych blokowania i odblokowywania kolejki, co prawdopodobnie oznacza, że ​​cały czas się dzieje.

+3

Na boku, CPython ma pojęcie "GIL" (Global Interpreter Lock), które zasadniczo czyni CPython bezużytecznym dla "threading for performance" (NIE będzie skalowalne na rdzeniach), chociaż wątki w pythonie wciąż mogą być używane do ominięcia ograniczenie wywołań blokujących (systemowych). (Nie dotyczy to przypadków wywołujących wątkowe rozszerzenia C nie związane oczywiście z GIL). –

7

Ile procesorów posiadasz? Zasadniczo każde zadanie intensywne obliczania będzie wolniejsze, gdy liczba wątków> liczba procesorów. Dzieje się tak dlatego, że przełączanie się pomiędzy wątkami jest drogie ("przełącznik kontekstowy"). Przełączniki kontekstowe obejmują zatrzymanie 1 wątku, zapisanie jego kontekstu, a następnie wprowadzenie kontekstu innego wątku do procesora, aby mógł on działać. I za co? Zatem wątek A może obliczyć, czy 12321 jest podzielne przez 7 zamiast wątku B?

Jeśli masz 2 procs, założę się, że wersja z 2 wątków może być najszybszy, 4 procuje -> użyj 4 gwinty itp

+0

Próbowałem go na pudełku jedno-rdzeniowym 1x i pudełku 2x-czterordzeniowym. Obie miały podobnie kontrastujące wyniki. –

15

Jay P. ma rację:

~$ strace -c ./threads.pl 
% time  seconds usecs/call  calls errors syscall 
------ ----------- ----------- --------- --------- ---------------- 
99.80 0.116007  10546  11   futex 
    0.20 0.000229   6  36   mmap2 
    0.00 0.000000   0  31   read 
    0.00 0.000000   0  49  13 open 
    0.00 0.000000   0  36   close 

Porównaj to z:

~$ strace -c ./no-threads.pl 
% time  seconds usecs/call  calls errors syscall 
------ ----------- ----------- --------- --------- ---------------- 
90.62 0.000261   261   1   execve 
    9.38 0.000027   0  167   write 
    0.00 0.000000   0  12   read 
    0.00 0.000000   0  38  13 open 
    0.00 0.000000   0  25   close 
+0

Dzięki za potwierdzenie. Chciałbym móc przyjąć dwie odpowiedzi. ;) –

2

To trochę patologicznego przypadku. Prawdziwa odpowiedź brzmi: Zanim zaczniesz używać Perith ithreads, musisz wiedzieć trochę, jak działają. W niektórych przypadkach są one nieefektywne (dzielenie się danymi) i dobre w innych (są współbieżne).

Jeśli fragmenty pracy, które pozwolisz pod-wątkom, zostałyby zwiększone o znaczącą wartość w porównaniu do liczby wysyłanych danych z jednego wątku do drugiego, rzeczy wyglądałyby zupełnie inaczej.

Porównanie z wątkami w Pythonie, takimi jak Jay P: Jak poprawnie stwierdza, wątki Pythona są oparte na współpracy i działają tylko na jednym rdzeniu. Ekscelencje Perla są bardzo różne. Mogą one działać na rdzeniu, ale można to zrobić za pomocą oddzielnego interpretera na wątek. Dzięki temu komunikacja między wątkami jest podobna do komunikacji międzyprocesowej, w tym związanego z nią narzutów.

Powiązane problemy