24

Estoy haciendo un programa para ejecutar simulaciones en Python, con una interfaz wxPython. En el programa, puede crear una simulación, y el programa la representa (= calcula) por usted. La representación puede tomar mucho tiempo a veces.Multiprocesamiento o multiprocesamiento?

Cuando el usuario inicia una simulación y define un estado inicial, quiero que el programa muestre la simulación continuamente en segundo plano, mientras que el usuario puede estar haciendo cosas diferentes en el programa. Algo así como una barra de estilo de YouTube que se llena: puedes reproducir la simulación solo hasta el punto que se procesó.

¿Debo usar múltiples procesos o múltiples hilos, o qué? La gente me dijo que usara el paquete multiprocessing, lo revisé y se ve bien, pero también escuché que los procesos, a diferencia de los hilos, no pueden compartir mucha información (y creo que mi programa necesitará compartir mucha información). .) Además, también escuché sobre Stackless Python: ¿Es una opción separada? No tengo idea.

Por favor, asesorar.

+0

Me preocupa su "Creo que mi programa necesitará compartir mucha información", ¿quiere decir que aún no lo sabe? Tal vez deberías estar haciendo más trabajo de diseño. El módulo de multiprocesamiento es poco compatible con el módulo de roscado, por lo que la conmutación no debería ser un gran esfuerzo. Pero ten cuidado con GIL que me haría favorecer el multiprocesamiento. – CyberFonic

Respuesta

1

Siempre prefiero los subprocesos múltiples por simplicidad, pero hay un problema real con la afinidad. No hay forma (que yo sepa) de decirle a la implementación de subprocesos de Python que se vincule a un procesador específico. Esto puede no ser un problema para ti, no suena como debería ser. A menos que tenga una buena razón para no hacerlo, parece que su problema se puede resolver fácilmente con la implementación de enhebrado de Python.

Si decide usar procesado, compartir información entre subprocesos puede lograrse de varias maneras: conexiones tcp/udp, memoria compartida o canalizaciones. Agrega algunos sobrecarga y complejidad.

+1

+1: Threading es un formato muy, muy natural para trabajar con GUIs basadas en eventos, y lo ayuda a evitar el dolor de la comunicación entre procesos (a menos que sus necesidades de intercambio de información sean adecuadas para las opciones limitadas que Shane mencionó). – ojrac

+1

1. ¿Los subprocesos aprovecharían automáticamente todos los núcleos de la CPU? 2. ¿Tiene una idea de cómo Stackless encaja en todo esto? –

+0

Lo que pasa con los hilos es que "en general" están bajo el control del sistema operativo, y todos los sistemas operativos son una buena manera de distribuir las cargas entre las CPU. Este es generalmente el comportamiento que desea. Sin embargo, puede imaginar escenarios en los que le gustaría agregar una sola tarea a una sola CPU. –

18

"Lo he comprobado y se ve bien, pero también he oído que los procesos, a diferencia de las discusiones, no pueden compartir una gran cantidad de información ..."

Esto es cierto sólo en parte.

Los subprocesos son parte de un proceso: los subprocesos comparten la memoria trivialmente. Que es tanto un problema como una ayuda: dos hilos con indiferencia casual el uno al otro pueden sobrescribir la memoria y crear problemas graves.

Los procesos, sin embargo, comparten información a través de muchos mecanismos. Una canalización de Posix (a | b) significa que el proceso a y el proceso b comparten información, la escribe yb la lee. Esto funciona muy bien para muchas cosas.

El sistema operativo asignará sus procesos a cada núcleo disponible tan pronto como los cree. Esto funciona muy bien para muchas cosas.

Stackless Python no está relacionado con esta discusión, es más rápido y tiene una programación de subprocesos diferente. Pero no creo que los hilos sean la mejor ruta para esto.

"Creo que mi programa necesitará compartir mucha información".

Primero debe resolver esto. Luego, determine cómo estructurar los procesos en torno al flujo de información. Una "tubería" es muy fácil y natural de hacer; cualquier caparazón creará la tubería trivialmente.

Un "servidor" es otra arquitectura donde los procesos de múltiples clientes obtienen y/o colocan información en un servidor central. Esta es una gran manera de compartir información. Puede usar la implementación de referencia WSGI como una forma de construir un servidor simple y confiable.

14
  • Stackless: utiliza 1 cpu. "Tasklets" debe ceder voluntariamente. La opción de preferencia no funciona todo el tiempo.
  • Rosca: utiliza 1 cpu. Los subprocesos nativos comparten el tiempo un tanto al azar después de ejecutar 20-100 códigos de operación de Python.
  • multiprocesamiento: utiliza múltiples CPU

actualización

Indepth Análisis

Uso roscado para un momento fácil. Sin embargo, si llama a las rutinas C que toman un tiempo largo antes de regresar, esta puede no ser una opción si su rutina C no libera el bloqueo.

Utilice el multiprocesamiento si es muy limitado por la potencia de la CPU y necesita la máxima capacidad de respuesta.

No use stackless, he tenido segfault before y los threads son prácticamente equivalentes a menos que esté usando cientos de ellos o más.

+5

Esa es la primera vez que escucho a alguien decir que enhebrar fue fácil. El código de la OMI es muy difícil de escribir bien. –

5

Con CPython, varios subprocesos no se pueden ejecutar al mismo tiempo debido a GIL: link text.

Creo que todavía es posible que los subprocesos impulsen su aplicación, p. un hilo puede bloquearse en E/S mientras otro hace algo de trabajo.

Si nunca ha usado hilos, le sugiero que los pruebe primero. Será útil en cualquier otro idioma, y ​​encontrará muchos recursos en la web. Entonces, si se da cuenta de que necesita más paralelismo, aún puede volver a los procesos.

10

Un proceso tiene su propio espacio de memoria. Hace que sea más difícil compartir información, pero también hace que el programa sea más seguro (menos necesidad de sincronización explícita). Dicho esto, los procesos pueden compartir la misma memoria en modo de solo lectura.

Un hilo es más barato de crear o matar, pero la principal diferencia es que comparte la memoria con otros hilos en el mismo proceso. Esto a veces es arriesgado, y además bloquear el proceso mataría a todos los hilos.

Una de las ventajas del uso de múltiples procesos en múltiples hilos es que sería más fácil escalar su programa para trabajar con múltiples máquinas que se comunican a través de protocolos de red.

Por ejemplo, podría ejecutar 16 procesos en 8 máquinas de doble núcleo, pero no tendría un beneficio de más de 4 subprocesos en una máquina de cuatro núcleos. Si la cantidad de información que necesita para comunicarse es baja, el multiprocesamiento puede tener más sentido.

En cuanto al estilo de youtube que ha descrito, diría que sugiere el multiprocesamiento. Si sigue los enfoques de MVC, su GUI no debería contener el modelo (resultado del cálculo). Con multiproceso, puede comunicarse con un administrador de trabajo que puede informar qué datos ya están disponibles.

+0

"los procesos pueden compartir la misma memoria en modo de solo lectura" Creo que me será muy útil. ¿Cómo puedo hacer eso? –

+0

En la mayoría de los sistemas UNIX, cuando bifurca un proceso (crea uno a partir del otro), se supone que comparten las mismas páginas de lectura hasta que escriben. Guarda cargar el código del programa. Pero no es tan útil como una técnica de programación. – Uri

+0

Desafortunadamente, en Windows no es el caso (windows no tiene disponible os.fork). –

14

Hubo una buena charla sobre multiprocesamiento en Pycon este año.El mensaje para llevar era "Solo use multiprocesamiento a menos que esté seguro de que tiene un problema que resolverá, que no se puede resolver con hilos, de lo contrario, use hilos".

Los procesos tienen una gran sobrecarga, y todos los datos que se compartirán entre los procesos deben ser serializables (es decir, encuadrable).

Se puede ver las diapositivas y vídeo aquí: http://blip.tv/pycon-us-videos-2009-2010-2011/introduction-to-multiprocessing-in-python-1957019

http://us.pycon.org/2009/conference/schedule/event/31/

+3

Eso es desafortunado, ya que eso es casi lo opuesto a lo que harías en otros idiomas cuando fuera posible. Los subprocesos son propensos a errores y limitados en comparación con los procesos, y en Python se obtiene el problema GIL para agregar insulto a la lesión. – Kylotan

+9

si bien es cierto que varios procesos tienen un poco de sobrecarga de tiempo de ejecución (aunque eso es mucho menos cierto de lo que era hace cinco o diez años), el código enhebrado tiene una gran cantidad de sobrecarga de programación. Se necesitan personas inteligentes para escribir un buen código de subprocesos y _muy_personas inteligentes para depurarlo. –

+1

¿Hay un enlace actualizado a estas diapositivas/conversación? El enlace actual parece estar abajo. – Tyler

0

Suena como te gustaría roscado.

De la forma en que lo describió, sonaba como si hubiera una sola cosa que realmente requiriera una gran cantidad de CPU ... el funcionamiento real de la simulación.

Lo que intenta obtener son pantallas más receptivas, permitiendo la interacción del usuario y actualizaciones de gráficos mientras se ejecuta la simulación. Esto es exactamente para lo que se construyó el subproceso de python.

Lo que esto NO le conseguirá es la capacidad de aprovechar los múltiples núcleos/procesadores en su sistema. No tengo idea de cómo se ve tu simulación, pero si es una CPU intensiva, podría ser un buen candidato para dividirte. En este caso, puede usar multiprocesamiento para ejecutar partes separadas de la simulación en núcleos/procesadores independientes. Sin embargo, esto no es trivial ... ahora necesita alguna forma de pasar datos de vuelta a la cuarta parte entre los procesos, ya que los procesos separados no pueden acceder fácilmente al mismo espacio de memoria.

4

Si desea leer una larga discusión sobre el multi-threading en Mozilla, considere echar un vistazo a this discussion que comenzó en 2000. La discusión no necesariamente responde a su pregunta. Sin embargo, es una discusión en profundidad que creo que es interesante e informativa, la cual sugiero que puede ser muy valiosa porque usted hizo una pregunta difícil. Espero que te ayude a tomar una decisión informada.

Por cierto, varios miembros del proyecto Mozilla (especialmente Brendan Eich, CTO de Mozilla y el creador de JavaScript) fueron bastante críticos con el multi-threading en particular. Parte del material al que se hace referencia en here, here, here y here es compatible con dicha conclusión.

Espero que ayude y buena suerte.

1

Muy perplejo. Bastien Léonard señaló correctamente que el GIL detendrá cualquier habilidad para usar el enhebrado de alguna manera útil. Sus estados de referencia:

"Uso de un cierre global del intérprete en un idioma que efectivamente limita la cantidad de paralelismo accesible a través de la concurrencia de un solo proceso intérprete con múltiples hilos Si el proceso es casi puramente compone de. código interpretado y no hace llamadas fuera de el intérprete durante largos períodos de tiempo (que puede liberar el bloqueo en el GIL en ese subproceso mientras se procesa), es probable que haya muy poco aumento en la velocidad cuando se ejecuta el proceso en una máquina multiprocesador . Debido a la señalización con un subproceso vinculado a la CPU, es puede causar una desaceleración significativa, incluso en procesadores únicos ".

En este caso, el multiprocesamiento es la elección sensata.Desde mi propia experiencia, Python + MT no ofrece beneficios apreciables para el usuario.