python - parallel - Multiprocesamiento o multiproceso?
procesos concurrentes python (9)
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 renderización puede llevar mucho tiempo a veces.
Cuando el usuario inicia una simulación y define un estado inicial, quiero que el programa rinda la simulación continuamente en segundo plano, mientras que el usuario puede hacer cosas diferentes en el programa. Algo así como una barra de estilo de YouTube que se llena: puede reproducir la simulación solo hasta el punto en que se representó.
¿Debo usar múltiples procesos o múltiples hilos o qué? La gente me dijo que usara el paquete de multiprocessing
, lo comprobé y se ve bien, pero también escuché que los procesos, a diferencia de los subprocesos, no pueden compartir mucha información (y creo que mi programa tendrá que compartir mucha información) .) Además, también escuché sobre Stackless Python: ¿Es una opción separada? No tengo idea.
Por favor avise.
Con CPython, varios subprocesos no se pueden ejecutar al mismo tiempo debido al texto de enlace GIL :.
Creo que todavía es posible que los subprocesos mejoren su aplicación, por ejemplo, un subproceso puede bloquearse en la E / S mientras que otro hace algún 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.
Hubo una buena charla sobre multiprocesamiento en Pycon este año. El mensaje principal fue "Use solo multiprocesamiento a menos que esté seguro de que tiene un problema que resolverá, que no se puede resolver con subprocesos; de lo contrario, use subprocesos".
Los procesos tienen muchos gastos generales, y todos los datos que se comparten entre procesos deben ser serializables (es decir, seleccionables).
Puede ver las diapositivas y el video aquí: http://blip.tv/pycon-us-videos-2009-2010-2011/introduction-to-multiprocessing-in-python-1957019
Muy desconcertado. Bastien Léonard señaló acertadamente que la GIL detendrá cualquier habilidad para usar el enhebrado de cualquier manera útil. Su referencia establece:
"El uso de un bloqueo de intérprete global en un idioma limita efectivamente la cantidad de paralelismo que se puede alcanzar mediante la concurrencia de un solo proceso de intérprete con varios subprocesos. Si el proceso está compuesto casi exclusivamente de código interpretado y no hace llamadas fuera del intérprete por mucho tiempo. períodos de tiempo (que pueden liberar el bloqueo en el GIL en ese subproceso mientras se procesa), es probable que haya un aumento muy pequeño 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, puede causar una desaceleración significativa, incluso en procesadores individuales ".
Siendo este el caso, el multiprocesamiento es la opción sensata. Desde mi propia experiencia, Python + MT no supone un beneficio para el usuario.
Si desea leer una larga discusión sobre subprocesos múltiples en Mozilla, considere echar un vistazo a esta discusión 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, que sugiero puede ser bastante valiosa porque me has hecho una pregunta difícil. Esperemos que te ayude a tomar una decisión informada.
Por cierto, varios miembros del proyecto Mozilla (especialmente Brendan Eich, el CTO de Mozilla y el creador de JavaScript) fueron bastante críticos con los subprocesos múltiples en particular. Parte del material al que se hace referencia here , here , here y here apoya esta conclusión.
Espero que ayude y buena suerte.
Siempre prefiero múltiples subprocesos por simplicidad, pero hay un problema real con la afinidad. No hay manera (que yo sepa) de decirle a la implementación de subprocesos de Python que se enlace a un procesador específico. Esto puede no ser un problema para usted, no suena como debería ser. A menos que tenga una buena razón para no hacerlo, parece que su problema puede resolverse fácilmente con la implementación de subprocesos de Python.
Si decide utilizar procesado, compartir información entre subprocesos se puede lograr de varias formas: conexiones tcp / udp, memoria compartida o tuberías. Añade algunos gastos generales y complejidad.
Suena como si quisieras hilos.
La forma en que lo describiste, parecía que había una sola cosa que en realidad requería mucha CPU ... la ejecución real de la simulación.
Lo que está tratando de obtener es una pantalla más sensible, al permitir la interacción del usuario y las actualizaciones de gráficos mientras se ejecuta la simulación. Esto es exactamente para lo que Python fue construido.
Lo que esto NO le proporcionará es la posibilidad de aprovechar múltiples núcleos / procesadores en su sistema. No tengo idea de cómo es tu simulación, pero si se trata de un uso intensivo de la CPU, podría ser un buen candidato para dividirse. En este caso, puede usar el multiprocesamiento para ejecutar partes separadas de la simulación en núcleos / procesadores separados. Sin embargo, esto no es trivial ... ahora necesita una forma de pasar los datos y el cuarto entre los procesos, ya que los procesos separados no pueden acceder fácilmente al mismo espacio de memoria.
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 subproceso es más barato de crear o eliminar, pero la principal diferencia es que comparte memoria con otros subprocesos en el mismo proceso. Esto es a veces arriesgado, y además fallar el proceso mataría todos los hilos.
Una de las ventajas de usar múltiples procesos en múltiples subprocesos 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 el beneficio de tener 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 has descrito, diría que sugiere multiprocesamiento. Si sigue los enfoques de MVC, su GUI no debe contener también el modelo (resultado del cálculo). Con multiproceso, puede comunicarse con un administrador de trabajo que puede informar qué datos ya están disponibles.
"Lo comprobé y se ve bien, pero también escuché que los procesos, a diferencia de los hilos, no pueden compartir mucha información ..."
Esto sólo es parcialmente cierto.
Los hilos forman parte de un proceso: los hilos comparten la memoria de forma trivial. Lo que es tanto un problema como una ayuda: dos hilos con un desprecio casual el uno del otro pueden sobrescribir la memoria y crear problemas graves.
Los procesos, sin embargo, comparten información a través de muchos mecanismos. Un oleoducto de Posix ( a | b
) significa que el proceso a y el proceso b comparten información: a lo escribe yb lo 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.
Python sin pila 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 tendrá que compartir mucha información".
Debes resolver esto primero. 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 shell creará la tubería trivialmente.
Un "servidor" es otra arquitectura en la que múltiples procesos del cliente obtienen y / o ponen información en un servidor central. Esta es una gran manera de compartir información. Puede utilizar la implementación de referencia de WSGI como una forma de construir un servidor simple y confiable.
- Apilable : utiliza 1 cpu. "Tasklets" debe ceder voluntariamente. La opción de preferencia no funciona todo el tiempo.
- Roscado : utiliza 1 cpu. Los subprocesos nativos comparten el tiempo de forma algo aleatoria después de ejecutar 20-100 opcodes de python.
- Multiprocesamiento : utiliza múltiples cpu.
Actualizar
Análisis en profundidad
Utilice roscado para un tiempo fácil. Sin embargo, si llama a las rutinas de C que tardan mucho tiempo antes de regresar, entonces esta puede no ser una opción si su rutina de C no libera el bloqueo.
Utilice el multiprocesamiento si está muy limitado por el poder de la CPU y necesita la máxima capacidad de respuesta.
No lo use sin apilar, lo he tenido de forma segura antes y los subprocesos son bastante equivalentes a menos que esté usando cientos de ellos o más.