Saltar al contenido

Paralelismo en Python

Nuestro equipo de trabajo ha estado mucho tiempo investigando para dar solución a tus dudas, te ofrecemos la resolución de modo que nuestro objetivo es que sea de gran ayuda.

Solución:

En general, describe un cálculo vinculado a la CPU. Este no es el fuerte de Python. Tampoco, históricamente, es el multiprocesamiento.

La creación de subprocesos en el intérprete principal de Python se ha regido por un temido bloqueo global. La nueva API de multiprocesamiento funciona en torno a eso y le brinda a un grupo de trabajadores una abstracción con conductos, colas y demás.

Puede escribir su código crítico de rendimiento en C o Cython, y usar Python para el pegamento.

El nuevo módulo de multiprocesamiento (2.6) es el camino a seguir. Utiliza subprocesos, lo que sortea el GIL problema. También abstrae algunos de los problemas locales/remotos, por lo que la elección de ejecutar su código localmente o distribuirlo en un clúster se puede realizar más adelante. La documentación que he vinculado anteriormente es un poco para masticar, pero debería proporcionar una buena base para comenzar.

Ray es una biblioteca elegante (y rápida) para hacer esto.

La estrategia más básica para paralelizar funciones de Python es declarar una función con el @ray.remote decorador. Entonces se puede invocar de forma asíncrona.

import ray
import time

# Start the Ray processes (e.g., a scheduler and shared-memory object store).
ray.init(num_cpus=8)

@ray.remote
def f():
    time.sleep(1)

# This should take one second assuming you have at least 4 cores.
ray.get([f.remote() for _ in range(4)])

También puede paralelizar el cálculo con estado usando actores, nuevamente usando el @ray.remote decorador.

# This assumes you already ran 'import ray' and 'ray.init()'.

import time

@ray.remote
class Counter(object):
    def __init__(self):
        self.x = 0

    def inc(self):
        self.x += 1

    def get_counter(self):
        return self.x

# Create two actors which will operate in parallel.
counter1 = Counter.remote()
counter2 = Counter.remote()

@ray.remote
def update_counters(counter1, counter2):
    for _ in range(1000):
        time.sleep(0.25)
        counter1.inc.remote()
        counter2.inc.remote()

# Start three tasks that update the counters in the background also in parallel.
update_counters.remote(counter1, counter2)
update_counters.remote(counter1, counter2)
update_counters.remote(counter1, counter2)

# Check the counter values.
for _ in range(5):
    counter1_val = ray.get(counter1.get_counter.remote())
    counter2_val = ray.get(counter2.get_counter.remote())
    print("Counter1: , Counter2: ".format(counter1_val, counter2_val))
    time.sleep(1)

Tiene una serie de ventajas sobre el módulo de multiprocesamiento:

  • El mismo código se ejecuta en una sola máquina multinúcleo, así como en un clúster grande.
  • Los datos se comparten de manera eficiente entre procesos en la misma máquina utilizando memoria compartida y serialización eficiente.
  • Puede paralelizar funciones de Python (usando tareas) y clases de Python (usando actores).
  • Los mensajes de error se propagan muy bien.

Ray es un marco que he estado ayudando a desarrollar.

Si entiendes que ha resultado de provecho nuestro post, nos gustaría que lo compartas con más entusiastas de la programación así nos ayudas a dar difusión a este contenido.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *