2010-08-10 18 views
6

Tengo una estructura de datos compleja (tipo definido por el usuario) en la que se realiza una gran cantidad de cálculos independientes. La estructura de datos es básicamente inmutable. Digo básicamente, porque aunque la interfaz parece inmutable, internamente se está realizando una evaluación diferida. Algunos de los atributos calculados de forma diferida se almacenan en diccionarios (valores de retorno de funciones costosas por parámetro de entrada). Me gustaría usar el módulo Pythons multiprocessing para paralelizar estos cálculos. Hay dos preguntas en mi mente.Compartir datos entre procesos en Python

  1. ¿Cuál es la mejor forma de compartir la estructura de datos entre procesos?
  2. ¿Hay alguna manera de manejar el problema de la evaluación diferida sin usar bloqueos (múltiples procesos escriben el mismo valor)?

¡Gracias de antemano por cualquier respuesta, comentario o aclaración!

+0

¿Qué tan grande/complejo estás hablando? Cuando se envía un "cálculo independiente", ¿sabe antes del inicio qué atributos perezosos se necesitan? – MattH

+0

El problema es básicamente una validación cruzada de dejar salir de una vez en un gran conjunto de muestras de datos. Me lleva unas dos horas en mi máquina en un solo núcleo, pero tengo acceso a una máquina con 24 núcleos y me gustaría aprovechar esa potencia. No sé de antemano cuál de los atributos será necesario para un solo cálculo, pero sé que eventualmente (sobre todos los cálculos) se necesitarán todos los atributos, así que podría simplemente cargarlos por adelantado (tendría que probar eso aunque) –

Respuesta

8

¿Cuál es la mejor forma de compartir la estructura de datos entre procesos?

Tuberías.

origin.py | process1.py | process2.py | process3.py 

Divida su programa para que cada cálculo sea un proceso separado del siguiente formulario.

def transform1(piece): 
    Some transformation or calculation. 

Para la prueba, se puede utilizar de esta manera.

def t1(iterable): 
    for piece in iterable: 
     more_data = transform1(piece) 
     yield NewNamedTuple(piece, more_data) 

Para reproducir todo el cálculo en un único proceso, se puede hacer esto.

for x in t1(t2(t3(the_whole_structure))): 
    print(x) 

Puede ajustar cada transformación con un poco de E/S de archivos. Pickle funciona bien para esto, pero otras representaciones (como JSON o YAML) también funcionan bien.

while True: 
    a_piece = pickle.load(sys.stdin) 
    more_data = transform1(a_piece) 
    pickle.dump(NewNamedTuple(piece, more_data)) 

Cada paso de procesamiento se convierte en un proceso de nivel de sistema operativo independiente. Se ejecutarán simultáneamente y, de forma inmediata, consumirán todos los recursos del nivel del sistema operativo.

¿Hay alguna manera de manejar el problema de la evaluación diferida sin utilizar bloqueos (múltiples procesos escriben el mismo valor)?

Tuberías.

+0

Guau, esa respuesta resuelve dos problemas que ni siquiera estaban en mi pregunta (cómo enviar un objeto complejo a otro proceso, cómo hacerlo en python cuando el módulo de multiprocesamiento no está disponible). –

+0

El punto es que la gestión del proceso del nivel del sistema operativo (búfer compartido) es (a) más simple y (b) puede ser tan rápida como las técnicas más complejas de subprocesos múltiples y de todo compartido. –

Cuestiones relacionadas