2010-08-29 9 views
5

me escribió un programa que llama a una función con el siguiente prototipo:¿Ejecutar varias instancias de un programa python de manera eficiente y económica?

def Process(n): 

    # the function uses data that is stored as binary files on the hard drive and 
    # -- based on the value of 'n' -- scans it using functions from numpy & cython.  
    # the function creates new binary files and saves the results of the scan in them. 
    # 
    # I optimized the running time of the function as much as I could using numpy & 
    # cython, and at present it takes about 4hrs to complete one function run on 
    # a typical winXP desktop (three years old machine, 2GB memory etc). 

Mi objetivo es ejecutar esta función exactamente 10.000 veces (para 10.000 valores diferentes de 'n') en el & forma más económica más rápida. Después de estas ejecuciones, tendré 10.000 archivos binarios diferentes con los resultados de todos los escaneos individuales. tenga en cuenta que cada función 'ejecutar' es independiente (es decir, no hay dependencia alguna entre las ejecuciones individuales).

Así que la pregunta es esta. teniendo solo una PC en casa, es obvio que me tomará alrededor de 4.5 años (10,000 carreras x 4 horas por ciclo = 40,000 hrs ~ = 4.5 años) para completar todas las carreras en casa. sin embargo, me gustaría tener todas las corridas completadas dentro de una semana o dos.

Sé que la solución implicaría acceder a muchos recursos informáticos a la vez. ¿Cuál es la mejor forma (más rápida/más asequible, ya que mi presupuesto es limitado) de hacerlo? debo comprar un servidor fuerte (¿cuánto costaría?) o ¿puedo ejecutarlo en línea? en tal caso, ¿se expone mi código propietario al hacerlo?

en caso de que ayude, cada instancia de 'Process()' solo necesita alrededor de 500MB de memoria. Gracias.

+2

¿Qué significa 'Process'? Sin más información, no creo que sea fácil mejorar la velocidad más de 2 veces (asumiendo el doble núcleo). – kennytm

+0

KennyTM: gracias por su respuesta. incluso si el tiempo de ejecución disminuye a la mitad (lo cual es poco probable), me tomará 2.5 años ejecutarlo todo. por lo tanto, el foco aquí está en el lado de la paralelización del problema. si tienes una buena idea para esto, sería genial. –

Respuesta

1

¿Tiene acceso Process directamente a los datos en los archivos binarios o lo almacena en la memoria caché? Reducir el uso de operaciones de E/S debería ayudar.

Además, ¿no es posible dividir Process en funciones separadas que se ejecutan en paralelo? ¿Cómo es la dependencia de datos dentro de la función?

Por último, podría intentar con algún servicio de computación en la nube como Amazon EC2 (no olvide leer this para herramientas), pero no será barato (EC2 comienza a $ 0.085 por hora) - una alternativa iría a una universidad con un grupo de computadoras (son bastante comunes hoy en día, pero será más fácil si conoces a alguien allí).

+0

bnery: los archivos binarios no se almacenan en la memoria caché, ya que son demasiado grandes y no caben en la memoria. Leo los archivos usando numpy's mmap(), que es muy, muy rápido. –

9

Salida PiCloud: http://www.picloud.com/

import cloud 
cloud.call(function) 

Tal vez es una solución fácil.

+0

muy interesante. Gracias por traer esto a mi atención. –

+0

+1 para el enlace a PiCloud ... bastante interesante :) – elo80ka

1

Bueno, según su descripción, parece que las cosas están unidas por IO ... En cuyo caso el paralelismo (al menos en un dispositivo IO) no ayudará mucho.

Editar: Me acabo de dar cuenta de que se refería más a la computación en nube completa, en lugar de ejecutar múltiples procesos en una máquina ... Mi consejo a continuación todavía se cumple, aunque ... PyTables es bastante bueno para la cálculos básicos!

Mencionaste que estás usando numpy's mmap para acceder a los datos. Por lo tanto, es probable que el tiempo de ejecución dependa en gran medida de cómo estén estructurados sus datos en el disco.

Memmapping en realidad puede ser bastante lento en cualquier situación donde el hardware físico tiene que pasar la mayor parte del tiempo buscando (por ejemplo, leyendo un corte a lo largo de un plano de Z constante en una matriz 3D ordenada por C). Una forma de mitigar esto es cambiar la forma en que se ordenan los datos para reducir la cantidad de búsquedas requeridas para acceder a las partes que es más probable que necesite.

Otra opción que puede ayudar es comprimir los datos.Si su proceso está extremadamente vinculado a IO, en realidad puede obtener aceleraciones significativas al comprimir los datos en el disco (y algunas veces incluso en la memoria) y descomprimirlos sobre la marcha antes de hacer su cálculo.

La buena noticia es que hay una biblioteca muy flexible y orientada a numpy que ya se ha creado para ayudarlo con ambos. Eche un vistazo al pytables.

Me sorprendería mucho que tables.Expr no significativamente (~ 1 orden de magnitud) supere su cálculo de fuera de núcleo mediante una matriz memmapped. See here para un buen ejemplo (aunque enlatado). De ese ejemplo:

PyTables vs Numpy Memmap

Cuestiones relacionadas