2009-11-07 4 views
8

A presentation por Mikhael Goikhman de una conferencia Perl 2003 incluye un par de ejemplos de scripts de búsqueda de números primos. One está enhebrado, y el other no lo está. Al ejecutar los guiones (líneas de impresión comentadas), obtuve un tiempo de ejecución de 0.011 en el no roscado, y 2.343 (!) Segundos en la versión roscada. ¿Qué explica la increíble diferencia en los tiempos?¿Por qué una versión en hilo de este script en particular de Perl es 200 veces más lenta que su contraparte sin subprocesos?

Tengo cierta experiencia con hilos en Perl y he notado antes que los tiempos de creación de hilos pueden ser particularmente brutales, pero esto no parece ser el cuello de botella en el ejemplo de Goikham.

+0

Tus enlaces "Uno" y "Otro" están al revés. – mob

+0

Se arregló ahora; Gracias. –

+0

Probablemente estés gastando 0.0055 segundos encontrando números primos ahora, y 2.3375 segundos haciendo que el problema sea thread-able. – jrockway

Respuesta

11

Soy un tipo de Python, Perl no, por lo que solo tiene una vaga idea de lo que está haciendo el código. Sin embargo, siempre tenga cuidado cuando vea Colas. Python tiene una cola segura para subprocesos, y parece que Perl también lo hace. Son fantásticos porque se encargan de la seguridad de los hilos, pero normalmente incluyen lotes de bloqueo y desbloqueo costosos de la cola, que es probablemente donde todo el tiempo va.

+3

Por otro lado, CPython tiene una noción del "GIL" (Bloqueo global de intérprete) que esencialmente hace que CPython sea inútil para "enhebrar para el rendimiento" (NO escalará a través de núcleos) aunque el enhebrado en python todavía se puede usar para limitación de llamadas de bloqueo (sistema). (Esto excluye los casos que invocan extensiones de C conscientes de hilos que no están relacionadas con el GIL, por supuesto). –

7

¿Cuántos procesadores tiene? En general, cualquier tarea de cálculo intensivo será más lenta cuando # de hilos> # de procesadores. Esto se debe a que es costoso cambiar entre subprocesos ("cambio de contexto"). Los interruptores de contexto implican detener 1 hilo, guardar su contexto y luego poner el contexto de otro hilo en el procesador para que pueda ejecutarse. Y todo por qué? ¿Entonces el hilo A puede calcular si 12321 es divisible por 7 en lugar del hilo B?

Si usted tiene 2 procsos, apostaría que una versión con 2 hilos podría ser el más rápido, 4 procsos -> Uso de 4 hilos, etc.

+0

Lo probé en una caja de 1 solo núcleo y en una caja de 2 x 4 núcleos. Ambos tuvieron resultados similarmente contrastivos. –

15

Jay P. tiene razón:

~$ 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 

compararlo con:

~$ 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

Gracias por la confirmación. Ojalá pudiera aceptar dos respuestas. ;) –

2

Es un poco de un caso patológico. La verdadera respuesta es: antes de comenzar a utilizar Perl ithreads, necesitas saber un poco sobre cómo funcionan las cosas. Son notoriamente ineficientes en algunas cosas (compartir datos) y buenas en otras (son concurrentes).

Si los trozos de trabajo que permite que los subprocesos realicen aumentan significativamente en comparación con el número de veces que envía datos de un hilo a otro, las cosas se verían bastante diferentes.

Comparando con hilos de Python como Jay P: Como él dice correctamente, los hilos de Python son cooperativos y se ejecutan solo en un núcleo. Los hilos de Perl son muy diferentes. Pueden ejecutarse en un núcleo cada uno, pero ser capaz de hacer esto se paga con tener esencialmente un intérprete por hilo por separado. Eso hace que la comunicación entre subprocesos sea similar a la comunicación entre procesos, incluida la sobrecarga asociada.

Cuestiones relacionadas