2009-10-19 7 views
10

Tengo el siguiente código escrito para que funcione mi segundo núcleo de CPU. Lo que hace básicamente el código es encontrar primero los archivos "mar" deseados en la jerarquía del directorio y luego ejecutar el conjunto de scripts externos para procesar estos archivos binarios "mar" para producir de 50 a 100 archivos de texto y binarios en número. Como el título de la pregunta sugiere de forma paralela para aumentar la velocidad de procesamiento.Uso del grupo de multiprocesamiento de trabajadores

Esta pregunta tiene su origen en la larga discusión que hemos estado teniendo en la lista de usuarios de IPython titulada como "Cannot start ipcluster". Comenzando con mi experimentación en las funcionalidades de procesamiento paralelo de IPython.

El problema es que no puedo obtener este código funcionando correctamente. Si las carpetas que contienen archivos "mar" solo albergan archivos "mar", el guión finaliza su ejecución sin ejecutar completamente las secuencias de comandos externas. (Digamos que tengo entre 30 y 50 scripts externos para ejecutar, pero mi script habilitado para multiprocesamiento se agota solo después de ejecutar el primer script en esta cadena de scripts externa.) Curiosamente, si ejecuto este script en una carpeta ya procesada (que es archivos "mar") procesados ​​de antemano y los archivos de salida ya están en esa carpeta) luego se ejecuta, pero esta vez obtengo aceleraciones de 2.4 a 2.7X con respecto a los tiempos de procesamiento lineal. No es muy esperado ya que solo tengo una CPU Core 2 Duo 2.5 Ghz en mi computadora portátil. Aunque tengo una GPU con CUDA, no tiene nada que ver con mi actual lucha paralela en la informática :)

¿Cuál crees que podría ser la causa de este problema?

Gracias por todos los comentarios y sugerencias.

#!/usr/bin/env python 

from multiprocessing import Pool 
from subprocess import call 
import os 


def find_sea_files(): 

    file_list, path_list = [], [] 
    init = os.getcwd() 

    for root, dirs, files in os.walk('.'): 
     dirs.sort() 
     for file in files: 
      if file.endswith('.sea'): 
       file_list.append(file) 
       os.chdir(root) 
       path_list.append(os.getcwd()) 
       os.chdir(init) 

    return file_list, path_list 


def process_all(pf): 
    os.chdir(pf[0]) 
    call(['postprocessing_saudi', pf[1]]) 


if __name__ == '__main__': 
    pool = Pool(processes=2)    # start 2 worker processes 
    files, paths = find_sea_files() 
    pathfile = [[paths[i],files[i]] for i in range(len(files))] 
    pool.map(process_all, pathfile) 
+0

En lugar de llamar a la secuencia de comandos externa superior, cuando intento llamar al subguión que forma parte de postprocessing_saudi, es decir, process_raw y ejecución, aparece un error misterioso: Lo siguiente es solo una parte del error. Como se muestra, la ejecución de IDL es confusa y no se puede obtener un resultado correcto. [gsever @ ccn partest] $ python proall3.py PID: 17722 PID: 17723 IDL Versión 7.1 (linux x86 m32). (c) 2009, ITT Visual Information Solutions IDL Versión 7.1 (Linux x86 m32). (c) 2009, ITT Visual Information Solutions % No se puede obtener el estado del archivo. Unidad: 0, archivo: Descriptor de archivo incorrecto –

Respuesta

6

Me gustaría empezar con conseguir una mejor idea de lo que está pasando con el proceso de trabajo. El módulo de multiprocesamiento viene con el registro de sus subprocesos si es necesario. Puesto que usted ha simplificado el código para reducir el problema, sólo quiero depurar con algunas declaraciones de impresión, al igual que (o puede prettyprint la matriz PF):


def process_all(pf): 
    print "PID: ", os.getpid() 
    print "Script Dir: ", pf[0] 
    print "Script: ", pf[1] 
    os.chdir(pf[0]) 
    call(['postprocessing_saudi', pf[1]]) 


if __name__ == '__main__': 
    pool = Pool(processes=2) 
    files, paths = find_sea_files() 
    pathfile = [[paths[i],files[i]] for i in range(len(files))] 
    pool.map(process_all, pathfile, 1) # Ensure the chunk size is 1 
    pool.close() 
    pool.join() 

La versión de Python que tengo Lo logró con 2.6.4.

+0

El script visita el primer directorio y sin iniciar el proceso de proceso externo el script va al segundo directorio y trata de procesar el primer archivo desde allí [gsever @ ccn partest] $ python proall3.py PID: 10723 Script dir:/home/gsever/escritorio/partest/20090317_131342/post-procesamiento Guión: 09_03_17_13_13_42.sea PID: 10724 script dir:/home/gsever/escritorio/partest/20090318_075533/post-procesamiento Guión: 09_03_18_07_55_33.sea Procesamiento de la 09_03_18_07_55_33 Archivo .sea ....................... Procesando el archivo 09_03_17_13_13_42.sea .................. ..... Hecho –

+0

Nuevamente, la ejecución falla sin siquiera aplicar correctamente el script externo ch ain en cada archivo de mar. Sigo pensando que el problema está relacionado con el módulo de multiprocesamiento de Python. Me gustaría escuchar algunos comentarios más para resolver el problema exacto. –

3

Hay varias cosas que se me ocurren:

1) ¿Ha impreso el pathfiles? ¿Estás seguro de que todos están bien generados?

a) Pregunto porque os.walk es un poco interesante; el dirs.sort() debería estar bien, pero parece bastante innecesario. os.chdir() en general no debería ser usado; la restauración debería estar bien, pero en general solo debería agregar root a init.

2) He visto el multiproceso en python2.6 tener problemas para generar subporcesos de las agrupaciones. (Específicamente, un script usa multiprocesamiento para generar subprocesos. Esos subprocesos no podían usar correctamente el multiprocesamiento (el grupo bloqueado)). Pruebe python2.5 con el backport multiproceso.

3) Pruebe el módulo cloud.mp de picloud (que ajusta el multiprocesamiento, pero maneja las piscinas un poco diferente) y vea si eso funciona.

Harías

cloud.mp.join(cloud.mp.map(process_all, pathfile)) 

(Negación: Soy uno de los desarrolladores de PiCloud)

+0

1) Sí, las rutas son todas correctas. Probé las mismas rutas utilizando las funciones de procesamiento en paralelo de IPython y el script principal pasa por las carpetas y ejecuta la cadena de scripts mencionada correctamente para procesar por completo los archivos marinos. a) sort() es una alternativa para el sistema de archivos de Fedora (ext4). Sin él, os.walk() visita las carpetas arbitrariamente. 2) Echaré un vistazo a 2.5. Ahora uso 2.6.0 3) Gracias por la sugerencia. Lo probaré, sin embargo, tiendo a no agregar requisitos externos para que otros puedan ejecutar fácilmente el script. –

Cuestiones relacionadas