Python Multiprocessing innerhalb von mpi
Ich habe ein Python-Skript, das ich mit dem Multiprocessing-Modul geschrieben habe, um die Ausführung zu beschleunigen. Die Berechnung verläuft peinlich parallel, sodass die Effizienz mit der Anzahl der Prozessoren skaliert. Jetzt möchte ich dies in einem MPI-Programm verwenden, das eine MCMC-Berechnung auf mehreren Computern verwaltet. Dieser Code hat einen Aufruf an system (), der das Python-Skript aufruft. Ich stelle jedoch fest, dass der Effizienzgewinn durch die Verwendung von Python Multiprocessing verschwindet, wenn man es so nennt.
Wie kann ich erreichen, dass mein Python-Skript die Geschwindigkeitszuwächse aus der Mehrfachverarbeitung beibehält, wenn es von MPI aufgerufen wird?
Here ist ein einfaches Beispiel, das den viel komplizierteren Codes entspricht, die ich verwenden möchte, aber dasselbe allgemeine Verhalten zeigt. Ich schreibe ein ausführbares Python-Skript namens junk.py.
#!/usr/bin/python
import multiprocessing
import numpy as np
nproc = 3
nlen = 100000
def f(x):
print x
v = np.arange(nlen)
result = 0.
for i, y in enumerate(v):
result += (x+v[i:]).sum()
return result
def foo():
pool = multiprocessing.Pool(processes=nproc)
xlist = range(2,2+nproc)
print xlist
result = pool.map(f, xlist)
print result
if __name__ == '__main__':
foo()
Wenn ich dies von der Shell aus selbst ausführe und "top" benutze, kann ich drei Python-Prozesse sehen, die jeweils 100% der CPU auf meinem 16-Core-Rechner beanspruchen.
node094:mpi[ 206 ] /usr/bin/time junk.py
[2, 3, 4]
2
3
4
[333343333400000.0, 333348333450000.0, 333353333500000.0]
62.68user 0.04system 0:21.11elapsed 297%CPU (0avgtext+0avgdata 16516maxresident)k
0inputs+0outputs (0major+11092minor)pagefaults 0swaps
Wenn ich dies jedoch mit mpirun aufrufe, benötigt jeder Python-Prozess 33% der CPU und insgesamt dauert die Ausführung etwa dreimal so lange. Das Aufrufen mit -np 2 oder mehr führt zu mehr Prozessen, beschleunigt jedoch die Berechnung nicht.
node094:mpi[ 208 ] /usr/bin/time mpirun -np 1 junk.py
[2, 3, 4]
2
3
4
[333343333400000.0, 333348333450000.0, 333353333500000.0]
61.63user 0.07system 1:01.91elapsed 99%CPU (0avgtext+0avgdata 16520maxresident)k
0inputs+8outputs (0major+13715minor)pagefaults 0swaps
(Zusätzliche Hinweise: Dies ist mpirun 1.8.1, python 2.7.3 unter Linux Debian Version wheezy. Ich habe gehört, dass system () in MPI-Programmen nicht immer erlaubt ist, aber es funktioniert seit fünf Jahren für mich auf diesem Computer Ich habe zum Beispiel einen pthread-basierten Parallelcode von system () innerhalb eines MPI-Programms aufgerufen, der je nach Wunsch 100% der CPU-Kapazität für jeden Thread verwendet und rufe es einfach auf mehr Knoten auf ... die MCMC-Berechnung beinhaltet eine feste Anzahl von Ketten, die sich synchron bewegen müssen, so dass die Berechnung leider nicht auf diese Weise reorganisiert werden kann.)