El por qué, cuándo y cómo usar Python Multi-threading y… – Hacia la IA

Estás leyendo la publicación: El por qué, cuándo y cómo usar Python Multi-threading y… – Hacia la IA

Esta guía tiene como objetivo explicar por qué se necesitan subprocesos múltiples y procesamiento múltiple en Python, cuándo usar uno sobre el otro y cómo usarlos en sus programas. Como investigador de IA, ¡los uso mucho cuando preparo datos para mis modelos!

Imagen por parker_oeste de pixabay

Hace mucho tiempo en una galaxia muy, muy lejana…

Un mago sabio y poderoso vive en un pequeño pueblo en medio de la nada. Llamémoslo Dumbledalf. No solo es sabio y poderoso, sino que también está feliz de ayudar a cualquiera que se lo pida y esto significa que la gente viene de todas partes para pedir ayuda al mago. Nuestra historia comienza cuando un buen día, un joven viajero le lleva un pergamino mágico al mago. El viajero no tiene idea de lo que contiene el pergamino, pero sabe que si alguien puede descifrar los secretos del pergamino, ese es el gran mago, Dumbledalf.

Capítulo 1: Proceso único de subproceso único

Si aún no lo ha adivinado, mi analogía bastante sensiblera es hablar de una CPU y sus funciones. Nuestro asistente es la CPU y el pergamino mágico es una lista de URL lo que conduce al poder de Python y al conocimiento para ejercer ese poder.

El primer pensamiento del mago, después de haber descifrado el pergamino sin demasiados problemas, fue enviar a su amigo de confianza (¿Haragorn? Lo sé, lo sé, eso es terrible) a cada uno de los lugares indicados en el pergamino para ver y recuperar lo que pueda encontrar.

Como puede ver, simplemente estamos avanzando pesadamente a través del URL uno por uno usando un bucle for y leyendo la respuesta. Gracias a %%time la magia de IPython, podemos ver que tarda unos 12 segundos con mi deplorable internet.

Capítulo 2: Subprocesamiento múltiple

No en vano, la sabiduría del mago se hizo famosa en todo el país, y rápidamente se le ocurrió un método mucho más eficiente. En lugar de enviar a una persona a cada una de las ubicaciones en orden, ¿por qué no reunir a un grupo de personas (de confianza) y enviarlas por separado a cada una de las ubicaciones? ¡al mismo tiempo! El mago simplemente puede combinar todo lo que traen una vez que todos regresan.

Así es, en lugar de recorrer la lista una por una, podemos usar subprocesos múltiples para acceder a múltiples URL al mismo tiempo.

¡Mucho mejor! Casi como… magia. El uso de múltiples subprocesos puede acelerar significativamente muchas tareas que son enlazado a IO. Aquí, la gran parte del tiempo empleado en leer el URL se debe al retraso de la red. enlazado a IO los programas pasan la mayor parte de su tiempo esperando, lo adivinaste, entrada/salida (Al igual que el mago debe esperar a que su amigo/amigos vayan a las ubicaciones indicadas en el pergamino y regresen). Esto puede ser E/S de una red, una base de datos, un archivo o incluso un usuario. Esta E/S tiende a tomar una cantidad significativa de tiempo, ya que la fuente misma puede necesitar realizar su propio procesamiento antes de pasar la E/S. Por ejemplo, la CPU trabaja mucho, mucho más rápido de lo que una conexión de red puede transportar datos (Piensa en Flash contra tu abuela).

Nota: subprocesos múltiples puede ser muy útil en tareas como web scraping.

Capítulo 3: Multiprocesamiento

A medida que pasaban los años y la fama de nuestro mago crecía, también lo hacía la envidia de un mago oscuro bastante desagradable (¿Sarudort? ¿Voldeman?). Armado con astucia tortuosa e impulsado por los celos, el mago oscuro realizó una terrible maldición sobre Dumbledalf. Tan pronto como la maldición se asentó, Dumbledalf supo que solo tenía unos momentos para romperla. Desgarrando sus libros de hechizos con desesperación, encuentra un contrahechizo que parece que podría funcionar. El único problema es que requiere que calcule la suma de todos los números primos por debajo de 1000000. Hechizo extraño, pero es lo que es.

🔥 Recomendado:  ¡15 formas REALES de ganar dinero con Fiverr y trabajar como autónomo a tiempo completo!

Ahora, el mago sabe que calcular el valor será trivial dado el tiempo suficiente, pero el tiempo no es un lujo que tiene. Aunque es un mago, incluso él está limitado por su humanidad y solo puede calcular un número a la vez. Si tuviera que sumar los números primos uno por uno, le llevaría demasiado tiempo. Con segundos restantes para revertir la maldición, de repente recuerda el hechizo de procesamiento múltiple que aprendió del pergamino mágico hace años. Este hechizo le permitiría hacer copias de sí mismo, y dividir los números entre sus copias le permitiría verificar si varios números son primos simultáneamente. Finalmente, todo lo que tiene que hacer es sumar todos los números primos que él y sus copias descubren.

Dado que las CPU modernas generalmente tienen más de un solo núcleo, podemos acelerar Límite de CPU tareas utilizando el módulo de multiprocesamiento. Límite de CPU Las tareas son programas que dedican la mayor parte de su tiempo a realizar cálculos en la CPU (cálculos matemáticos, procesamiento de imágenes, etc.). Si los cálculos se pueden realizar de forma independiente, podemos dividirlos entre los núcleos de CPU disponibles, lo que aumenta significativamente la velocidad de procesamiento.

Todo lo que tienes que hacer es;

  1. Definir la función a aplicar
  2. Prepare una lista de elementos en los que se aplicará la función.
  3. Generar procesos usando multiprocessing.Pool. El número pasado a Pool() será el número de procesos generados. La incrustación dentro de una declaración with garantiza que los procesos se eliminen después de finalizar la ejecución.
  4. Combine las salidas usando la función de mapa de un proceso Pool. Las entradas a la función de mapa son la función que se aplicará a cada elemento y la lista de elementos.
🔥 Recomendado:  ¿Qué es el marketing entrante? 10 tácticas para captar compradores leales

Nota: La función se puede definir para realizar cualquier tarea que se pueda realizar en paralelo. Por ejemplo, la función puede contener código para escribir el resultado de un cálculo en un archivo.

Entonces, ¿por qué necesitamos multiprocesamiento y subprocesos múltiples por separado? Si trató de utilizar subprocesos múltiples para mejorar el rendimiento de un Límite de CPU tarea, puede notar que lo que realmente obtiene es un degradación en rendimiento ¡Herejía! Veamos por qué sucede esto.

Al igual que el mago está limitado por su naturaleza humana y solo puede calcular un número a la vez, Python viene con algo llamado Bloqueo de intérprete global (GIL). Python felizmente le permitirá generar tantos hilos como desee, pero el GIL asegura que solo uno de esos hilos alguna vez serán ejecutando en cualquier momento dado.

Por un enlazado a IO tarea, eso está perfectamente bien. Un subproceso envía una solicitud a una URL y, mientras espera una respuesta, ese subproceso se puede cambiar por otro subproceso que envía otra solicitud a otra URL. Dado que un subproceso no tiene que hacer nada hasta que recibe una respuesta, realmente no importa que solo un subproceso sea ejecutando en un momento dado.

Para Límite de CPU tarea, tener múltiples hilos es tan útil como los pezones en una coraza. Debido a que solo se ejecuta un subproceso a la vez, incluso si genera varios subprocesos y cada uno tiene su propio número para verificar calidad superior, la CPU todavía solo se ocupará de un subproceso a la vez. En efecto, los números aún se verificarán uno tras otro. La sobrecarga al tratar con subprocesos múltiples contribuirá a la degradación del rendimiento que puede observar si utiliza subprocesos múltiples en un Límite de CPU tarea.

Para sortear esta ‘limitación’, usamos el módulo de multiprocesamiento. En lugar de usar subprocesos, el multiprocesamiento usa, bueno, múltiples procesos. Cada proceso tiene su propio intérprete y espacio de memoria, por lo que el GIL no retrasará las cosas. En esencia, cada proceso usa un núcleo de CPU diferente para trabajar en un número diferente, al mismo tiempo. ¡Dulce!

Puede notar que la utilización de la CPU aumenta mucho más cuando se utiliza el multiprocesamiento en comparación con el uso de un bucle for simple o incluso con subprocesos múltiples. Esto se debe a que su programa utiliza múltiples núcleos de CPU, en lugar de un solo núcleo. ¡Ésto es una cosa buena!

🔥 Recomendado:  ¿Cómo monetizar un sitio de finanzas? [2023]

Tenga en cuenta que el multiprocesamiento viene con su propia sobrecarga para administrar múltiples procesos, que generalmente tiende a ser más pesada que la sobrecarga de subprocesos múltiples. (El multiprocesamiento genera un intérprete separado y asigna un espacio de memoria separado para cada proceso, ¡así que duh!). Esto significa que, como regla general, es mejor usar el subprocesamiento múltiple liviano cuando puede salirse con la suya (lea: enlazado a IO tareas). Cuando el procesamiento de la CPU se convierte en su cuello de botella, generalmente es hora de invocar el módulo de multiprocesamiento. Pero recuerda, con un gran poder viene una gran responsabilidad.

Si genera más procesos de los que su CPU puede manejar a la vez, notará que su rendimiento comienza a disminuir. Esto se debe a que el sistema operativo ahora tiene que hacer más trabajo intercambiando procesos dentro y fuera de los núcleos de la CPU, ya que tiene más procesos que núcleos. La realidad puede ser más complicada que una simple explicación, pero esa es la idea básica. Puede ver una caída en el rendimiento de mi sistema cuando llegamos a los 16 procesos. Esto se debe a que mi CPU solo tiene 16 núcleos lógicos.

Capítulo 4: TLDR;

  • Para enlazado a IO tareas, el uso de subprocesos múltiples puede mejorar el rendimiento.
  • Para enlazado a IO tareas, el uso de multiprocesamiento también puede mejorar el rendimiento, pero la sobrecarga tiende a ser mayor que el uso de subprocesos múltiples.
  • Python GIL significa que solo se puede ejecutar un subproceso en un momento dado en un programa de Python.
  • Para Límite de CPU tareas, el uso de subprocesos múltiples en realidad puede empeorar el rendimiento.
  • Para Límite de CPU tareas, el uso de multiprocesamiento puede mejorar el rendimiento.
  • ¡Los magos son geniales!

Con esto concluye esta introducción a multihilo y multiprocesamiento en Python. ¡Adelante y conquista!