Ho un file numpy.array di 640x480, ognuna delle quali è lunga 630 immagini. L'array totale è quindi 630x480x640. Voglio generare un'immagine media, nonché calcolare la deviazione standard per ogni pixel su tutte le 630 immagini.Python multiprocessing Pool.map sta chiamando aquire?
Questo è facilmente realizzabile da
avg_image = numpy.mean(img_array, axis=0)
std_image = numpy.std(img_array, axis=0)
Tuttavia, dato che corro questo per 50 o giù di lì tali matrici, ed avere una workstation filo 8 core/16, ho pensato che avrei avuto avidi e parallelizzare le cose con il multiprocessing.Pool .
Così ho fatto la seguente:
def chunk_avg_map(chunk):
#do the processing
sig_avg = numpy.mean(chunk, axis=0)
sig_std = numpy.std(chunk, axis=0)
return([sig_avg, sig_std])
def chunk_avg(img_data):
#take each row of the image
chunks = [img_data[:,i,:] for i in range(len(img_data[0]))]
pool = multiprocessing.Pool()
result = pool.map(chunk_avg_map, chunks)
pool.close()
pool.join()
return result
Tuttavia, ho visto solo un piccolo aumento di velocità. Inserendo le dichiarazioni di stampa in chunk_avg_map, sono stato in grado di determinare che solo uno o due processi vengono lanciati alla volta, anziché 16 (come mi aspetterei).
Allora ho fatto funzionare il mio codice attraverso Cprofile in ipython:
%prun current_image_anal.main()
Il risultato ha indicato che di gran lunga la maggior parte del tempo è stato speso nelle chiamate di acquisire:
ncalls tottime percall cumtime percall filename:lineno(function)
1527 309.755 0.203 309.755 0.203 {built-in method acquire}
che capisco di essere qualcosa fare con il blocco, ma non capisco perché il mio codice lo farebbe. Qualcuno ha qualche idea?
[EDIT] Come richiesto, ecco uno script eseguibile che dimostra il problema. Puoi tracciarlo con qualsiasi mezzo tu voglia, ma quando l'ho fatto ho scoperto che la quota dei leoni parte del tempo era occupata con le chiamate da acquisire, piuttosto che dire o std come mi sarei aspettato .
#!/usr/bin/python
import numpy
import multiprocessing
def main():
fake_images = numpy.random.randint(0,2**14,(630,480,640))
chunk_avg(fake_images)
def chunk_avg_map(chunk):
#do the processing
sig_avg = numpy.mean(chunk, axis=0)
sig_std = numpy.std(chunk, axis=0)
return([sig_avg, sig_std])
def chunk_avg(img_data):
#take each row of the image
chunks = [img_data[:,i,:] for i in range(len(img_data[0]))]
pool = multiprocessing.Pool()
result = pool.map(chunk_avg_map, chunks)
pool.close()
pool.join()
return result
if __name__ == "__main__":
main()
Cosa ti dà multiprocessing.cpu_count()? –
multiprocessing.cpu_count() restituisce 16, come previsto. –
Questo potrebbe non avere importanza, ma dovremmo 'chunk_avg (im_data)' essere 'chunk_avg (img_data)'? – unutbu