2013-08-07 14 views
15

Sto tentando di eseguire un semplice test utilizzando il multiprocessing. Il test funziona bene fino a quando non importa numpy (anche se non è usato nel programma). Ecco il codice:Multiprocessing incompatibile con NumPy

from multiprocessing import Pool 
import time 
import numpy as np #this is the problematic line 


def CostlyFunc(N): 
    """""" 
    tstart = time.time() 
    x = 0 
    for i in xrange(N): 
     for j in xrange(N): 
      if i % 2: x += 2 
      else: x -= 2  
    print "CostlyFunc : elapsed time %f s" % (time.time() - tstart) 
    return x 

#serial application 
ResultList0 = [] 
StartTime = time.time() 
for i in xrange(3): 
    ResultList0.append(CostlyFunc(5000)) 
print "Elapsed time (serial) : ", time.time() - StartTime 


#multiprocessing application 
StartTime = time.time() 
pool = Pool() 
asyncResult = pool.map_async(CostlyFunc, [5000, 5000, 5000]) 
ResultList1 = asyncResult.get() 
print "Elapsed time (multiporcessing) : ", time.time() - StartTime 

Se non importare numpy il risultato è:

CostlyFunc : elapsed time 2.866265 s 
CostlyFunc : elapsed time 2.793213 s 
CostlyFunc : elapsed time 2.794936 s 
Elapsed time (serial) : 8.45455098152 
CostlyFunc : elapsed time 2.889815 s 
CostlyFunc : elapsed time 2.891556 s 
CostlyFunc : elapsed time 2.898898 s 
Elapsed time (multiporcessing) : 2.91595196724 

il tempo totale trascorso è simile al tempo necessario per 1 processo, il che significa che il calcolo è stato parallelizzati. Se faccio importare numpy il risultato diventa:

CostlyFunc : elapsed time 2.877116 s 
CostlyFunc : elapsed time 2.866778 s 
CostlyFunc : elapsed time 2.860894 s 
Elapsed time (serial) : 8.60492110252 
CostlyFunc : elapsed time 8.450145 s 
CostlyFunc : elapsed time 8.473006 s 
CostlyFunc : elapsed time 8.506402 s 
Elapsed time (multiporcessing) : 8.55398178101 

Il tempo totale trascorso è la stessa per entrambi i metodi di serie e di multiprocessing, perché un solo core viene utilizzato. È chiaro che il problema deriva da Numpy. È possibile che io abbia un'incompatibilità tra le mie versioni di multiprocessing e NumPy?

Attualmente sto usando Python2.7, NumPy 1.6.2 e multiprocessing 0.70a1 su linux

+1

Questo è molto strano: sembra funzionare bene su OSX con Python 2.7 e NumPy 1.7. Dai tempi sembra che siano utilizzati tre core, ma il tempo di elaborazione è rallentato- puoi confermarlo? – Daniel

+0

Grazie per la risposta. Sono abbastanza sicuro che il calcolo sia effettuato su 1 solo core quando importo NumPy (ho controllato con mpstat (http://linuxcommand.org/man_pages/mpstat1.html)). Sembra che lo stesso core calcoli i 3 lavori contemporaneamente: quindi ogni lavoro richiede ~ 8.5 sec ma il tempo totale è anche ~ 8.5 sec. – user2660966

+0

Ho provato con numpy 1.6.1, numpy 1.6.2 e numpy 1.7.1 ... stesso problema – user2660966

risposta

2

(First Post scusate se non è ben formulato o allineata)

Ci si può fermare Numpy di utilizzare il multithreading dai seting le MKL_NUM_THREADS a 1

Sotto debian ho usato:

export MKL_NUM_THREADS=1 

Fonte da Related Post StackOverflow: Python: How do you stop numpy from multithreading?

Risultato:

[email protected]:~/tmp$ python multi.py 
CostlyFunc : elapsed time 3.847009 s 
CostlyFunc : elapsed time 3.253226 s 
CostlyFunc : elapsed time 3.415734 s 
Elapsed time (serial) : 10.5163660049 
CostlyFunc : elapsed time 4.218424 s 
CostlyFunc : elapsed time 5.252429 s 
CostlyFunc : elapsed time 4.862513 s 
Elapsed time (multiporcessing) : 9.11713695526 

[email protected]:~/tmp$ export MKL_NUM_THREADS=1 

[email protected]:~/tmp$ python multi.py 
CostlyFunc : elapsed time 3.014677 s 
CostlyFunc : elapsed time 3.102548 s 
CostlyFunc : elapsed time 3.060915 s 
Elapsed time (serial) : 9.17840886116 
CostlyFunc : elapsed time 3.720322 s 
CostlyFunc : elapsed time 3.950583 s 
CostlyFunc : elapsed time 3.656165 s 
Elapsed time (multiporcessing) : 7.399310112 

Non sono sicuro se questo aiuta, perché immagino che alla fine si desidera NumPy eseguire in parallelo magari cercare di regolare il numero di thread per NumPy alla vostra macchina.

+0

Alla persona che ha downvotato: in caso di downvote - per favore spiega perché e fai domande nella sezione commenti. – Jon

1

Dai commenti su sua domanda, uno sguardo a quel link @Ophion no, ma mi hanno contrassegnato come un duplicato di Why does multiprocessing use only a single core after I import numpy? - ali_m 22 agosto alle 09:06

vorrei controllare per vedere se stai usando una versione ottimizzata di BLAS. Ho scoperto che alcune installazioni generiche di numpy non forniscono e ottimizzano la versione di questa libreria. Dalla mia installazione è possibile notare che è il punto di libf77blas.so, libcblas.so, libatlas.so.

Qui ci sono le istruzioni per costruire una versione ottimizzata del BLAS: http://docs.scipy.org/doc/numpy/user/install.html

Dalla con in python:

numpy.core._dotblas importazione

>>> numpy.core._dotblas.__file__ 

## output: 

'PYTHONHOME/lib/python2.7/site-packages/numpy/core/_dotblas.so' 

dal vostro terminale:

$ ldd 'PYTHONHOME/lib/python2.7/site-packages/numpy/core/_dotblas.so' 
linux-vdso.so.1 => (0x00007fff241ff000) 
libf77blas.so => /opt/arch/intel/lib/libf77blas.so (0x00007f6050647000) 
libcblas.so => /opt/arch/intel/lib/libcblas.so (0x00007f6050429000) 
libatlas.so => /opt/arch/intel/lib/libatlas.so (0x00007f604fbf1000) 
libpython2.7.so.1.0 => 'PYTHONHOME/lib/libpython2.7.so.1.0 (0x00007f604f817000) 
libpthread.so.0 => /lib64/libpthread.so.0 (0x00007f604f5f9000) 
libc.so.6 => /lib64/libc.so.6 (0x00007f604f266000) 
libgfortran.so.3 => /usr/lib64/libgfortran.so.3 (0x00007f604ef74000) 
libm.so.6 => /lib64/libm.so.6 (0x00007f604ecef000) 
libdl.so.2 => /lib64/libdl.so.2 (0x00007f604eaeb000) 
libutil.so.1 => /lib64/libutil.so.1 (0x00007f604e8e8000) 

/lib64/ld-linux-x86-64.so.2 (0x0000003c75e00000)

Problemi correlati