2011-06-10 11 views
6

Estoy creando un programa que lee varios archivos y escribe un resumen de cada archivo en un archivo de salida. El tamaño del archivo de salida es bastante grande, por lo que mantenerlo en la memoria no es una buena idea. Estoy tratando de desarrollar una forma de multiprocesamiento para hacerlo. Hasta ahora, la forma más sencilla que he podido venir es:multiprocesamiento imap_unordered en python

pool = Pool(processes=4) 
it = pool.imap_unordered(do, glob.iglob(aglob)) 
for summary in it: 
    writer.writerows(summary) 

do es la función que resume el archivo. escritor es un objeto csv.writer

Pero la verdad es que todavía no entiendo multiprocessing.imap completamente. ¿Esto significa que 4 resúmenes se calculan en paralelo y que cuando leo uno de ellos, el 5 comienza a calcularse?

¿Hay una mejor manera de hacerlo?

Gracias.

Respuesta

4

processes=4 significa que el multiprocesamiento iniciará un grupo con cuatro procesos de trabajo y les enviará los elementos de trabajo. Idealmente, si su sistema lo admite, es decir, tiene cuatro núcleos o los trabajadores no están totalmente vinculados a la CPU, se procesarán 4 elementos de trabajo en paralelo.

No conozco la implementación de multiprocesamiento, pero creo que los resultados de do se almacenarán en caché internamente incluso antes de leerlos, es decir, el quinto elemento se computará una vez que se haya realizado un proceso con un elemento del primera ola.

Si hay una manera mejor depende del tipo de sus datos. La cantidad de archivos que hay en total que necesita el procesamiento, el tamaño de los objetos son summary etc Si usted tiene muchos archivos (digamos, más de 10 k), preparación de lotes ellos podría ser una opción, a través de

it = pool.imap_unordered(do, glob.iglob(aglob), chunksize=100) 

De esta manera, un elemento de trabajo no es un archivo, sino 100 archivos, y los resultados también se informan en lotes de 100. Si tiene muchos elementos de trabajo, la fragmentación reduce los gastos generales de decapado y deshace los objetos resultantes.

+1

"fragmentación reduce la sobrecarga de decapado y deshace los objetos resultantes". - Entonces, ¿por qué no hacer 'chunksize = len (iterable)/number of processes'? ¿Cuál es la compensación? –

+1

@ AdamParkin cada elemento no puede ser procesado a la misma velocidad por un procesador, usted quiere tener una pila de elementos "listos para ser despachados" para llenar los procesadores en espera. – Zenon

+0

hmm, supongo que debería tener algo como trabajos 'max (3 * nproc, len (it))', entonces. lo que significa 'chunksize = len (it)/max (3 * nproc, len (it))'. o hay una buena heurística? –

Cuestiones relacionadas