Ho una macchina con 24 core fisici (almeno mi è stato detto così) che eseguono Debian: Linux 3.2.0-4-amd64 #1 SMP Debian 3.2.68-1+deb7u1 x86_64 GNU/Linux
. Essa sembra essere corretta:Python: multiprocessing, 8/24 core caricati
[email protected]:~/$ cat /proc/cpuinfo | grep processor
processor : 0
processor : 1
<...>
processor : 22
processor : 23
Ho avuto alcuni problemi che tentano di caricare tutti i core con Python di multiprocessing.pool.Pool
. Ho usato Pool(processes=None)
; i documenti dicono che Python usa cpu_count()
se viene fornito None
.
Ahimè, solo 8 core sono stati caricati al 100%, altri sono rimasti inattivi (ho utilizzato htop
per monitorare il carico della CPU). Ho pensato che non posso cucinare Pools
correttamente e ho cercato di richiamare 24 processi "manualmente":
print 'Starting processes...'
procs = list()
for param_set in all_params: # 24 items
p = Process(target=_wrap_test, args=[param_set])
p.start()
procs.append(p)
print 'Now waiting for them.'
for p in procs:
p.join()
avevo 24 messaggi "auguri" dai processi ho iniziato:
Starting processes...
Executing combination: Session len: 15, delta: 10, ratio: 0.1, eps_relabel: 0.5, min_pts_lof: 5, alpha: 0.01, reduce: 500
< ... 22 more messages ... >
Executing combination: Session len: 15, delta: 10, ratio: 0.1, eps_relabel: 0.5, min_pts_lof: 7, alpha: 0.01, reduce: 2000
Now waiting for them.
Ma ancora solo 8 nuclei sono stati caricati:
ho letto qui sul SO che ci m possono essere problemi con numpy
, OpenBLAS e l'esecuzione multicore. Questo è il modo di iniziare il mio codice:
OPENBLAS_MAIN_FREE=1 python -m tests.my_module
E dopo tutte le importazioni che faccio:
os.system("taskset -p 0xff %d" % os.getpid())
Quindi, ecco la domanda: che cosa devo fare per avere il 100% -load su tutti i core? Questo è solo il mio scarso utilizzo di Python o ha qualcosa a che fare con le limitazioni del sistema operativo su macchine multicore?
AGGIORNATO: una cosa più interessante è qualche incongruenza nell'output htop
. Se guardi l'immagine sopra, vedrai che la tabella sotto le barre di caricamento della CPU mostra il 30-50% di carico per molto più di 8 core, che è decisamente diverso da quello che dicono le barre di caricamento. Quindi, top
sembra essere d'accordo con quelle barre: 8 core caricati al 100%, altri inattivi.
AGGIORNATO ANCORA UNA VOLTA:
Ho usato this rather popular post su SO quando ho aggiunto la linea os.system("taskset -p 0xff %d" % os.getpid())
dopo tutte le importazioni. Devo ammettere che non ho pensato troppo quando l'ho fatto, soprattutto dopo aver letto questo:
Con questa formazione incollato in dopo le importazioni di moduli, il mio esempio ora gira su tutti i core
Sono un uomo semplice. Vedo "funziona come un incantesimo", copio e incollo. Comunque, mentre giocavo con il mio codice, alla fine ho rimosso . Successivamente il mio codice ha iniziato l'esecuzione su tutti i 24 core per lo scenario di avvio "manuale" Process
. Per lo scenario Pool
, lo stesso problema rimaneva, indipendentemente dal fatto che il trucco di affinità fosse usato o meno.
Non penso che sia una risposta reale perché non so quale sia il problema con Pool
, ma almeno sono riuscito a caricare tutti i core completamente. Grazie!
Sei sicuro che si tratta di 1 scheda processore? Ho sentito dire che Python non può fare multiprocessing (usare più di 1 CPU) – deathangel908
@ deathangel908 Suppongo che abbia 4 CPU con 6 core ciascuno. Ma utilizza già più di 6 core, quindi non è il problema credo. – oopcode
@ deathangel908 che è errato: ci sono problemi nel ricevere il threading per usare tutte le risorse della macchina, ma il multiprocessing, usando processi unix separati, non è limitato da Python. La mia ipotesi è che ci sia qualche impostazione del kernel che non sia impostata correttamente come l'OP ha indovinato. – msw