Gibt es in Python Tools, die Matlabs Parfor ähneln? Ich habe diesen Thread gefunden , aber er ist vier Jahre alt. Ich dachte, vielleicht hat hier jemand neuere Erfahrungen.
Hier ist ein Beispiel für die Art von Dingen, die ich parallelisieren möchte:
X = np.random.normal(size=(10, 3))
F = np.zeros((10, ))
for i in range(10):
F[i] = my_function(X[i,:])
wo my_function
nimmt eine ndarray
von Größe (1,3)
und gibt einen Skalar.
Zumindest möchte ich mehrere Kerne gleichzeitig verwenden - wie parfor. Mit anderen Worten, nehmen Sie ein gemeinsames Speichersystem mit 8 bis 16 Kernen an.
python
parallel-computing
Paul G. Constantine
quelle
quelle
Antworten:
Joblib macht was Sie wollen. Das grundlegende Verwendungsmuster ist:
Dabei
arg_instances
ist eine Liste von Werten, für diemyfun
parallel berechnet wird. Die Haupteinschränkung ist, dassmyfun
es sich um eine Toplevel-Funktion handeln muss. Derbackend
Parameter kann entweder"threading"
oder sein"multiprocessing"
.Sie können der parallelisierten Funktion weitere allgemeine Parameter übergeben. Der Body von
myfun
kann auch auf initialisierte globale Variablen verweisen, die den untergeordneten Variablen zur Verfügung stehen.Argumente und Ergebnisse können mit dem Threading-Backend so ziemlich alles sein, aber die Ergebnisse müssen mit dem Multiprocessing-Backend serialisierbar sein.
Dask bietet auch ähnliche Funktionen. Es ist möglicherweise vorzuziehen, wenn Sie mit Kerndaten arbeiten oder versuchen, komplexere Berechnungen zu parallelisieren.
quelle
threading
Backend unter dem GIL-Engpass leidet und dasmultiprocessing
Backend aufgrund der Serialisierung aller Parameter und Rückgabewerte einen hohen Overhead verursacht. In dieser Antwort finden Sie Informationen zur Parallelverarbeitung in Python.map
, die Sie direkt verwenden können. Auch wenn Sie mkl compiled numpy verwenden, werden vektorisierte Operationen automatisch parallelisiert, ohne dass Sie etwas unternehmen. Die Nummer in Ananconda ist standardmäßig mkl-aktiviert. Es gibt jedoch keine universelle Lösung. Joblib ist sehr unkompliziert und es gab im Jahr 2015 weniger Probleme.Was Sie suchen, ist Numba , das eine for-Schleife automatisch parallelisieren kann. Aus ihrer Dokumentation
quelle
Ohne etwas Besonderes anzunehmen
my_function
Auswahl ,multiprocessing.Pool().map()
ist eine gute Vermutung für die Parallelisierung solcher einfachen Schleifen.joblib
,dask
,mpi
Berechnungen odernumba
in anderen Antworten vorgeschlagen wie nicht sieht keinen Vorteil für solche Anwendungsfälle und fügen nutzlos Abhängigkeiten zu bringen (summieren sie sind übertrieben). Es ist unwahrscheinlich, dass die in einer anderen Antwort vorgeschlagene Verwendung von Threading eine gute Lösung darstellt, da Sie mit der GIL-Interaktion Ihres Codes vertraut sein müssen oder Ihr Code hauptsächlich Eingabe / Ausgabe ausführen sollte.Das
numba
könnte eine gute Idee sein, um sequentiellen reinen Python-Code zu beschleunigen, aber ich glaube, dass dies außerhalb des Rahmens der Frage liegt.Es gibt jedoch einige Einschränkungen (die jedoch die meisten Anwendungen nicht beeinträchtigen sollten):
if __name__ == "__main__"
my_function
sollten nicht von gemeinsamen Zuständen abhängen, wie z. B. der Kommunikation mit globalen Variablen, da Zustände nicht zwischen Prozessen geteilt werden. reine Funktionen (Funktionen im mathematischen Sinne) sind Beispiele für Funktionen, die keine Zustände teilenquelle
Mein Eindruck von parfor ist, dass MATLAB Implementierungsdetails kapselt, sodass sowohl Shared-Memory-Parallelität (wie gewünscht) als auch Distributed-Memory-Parallelität (wenn Sie einen Distributed-Computing-Server von MATLAB ausführen ) verwendet werden können.
Wenn Sie Parallelität mit gemeinsam genutztem Speicher wünschen und eine Art Task-Parallel-Schleife ausführen, ist das Multiprocessing-Standardbibliothekspaket wahrscheinlich das, was Sie möchten, möglicherweise mit einem netten Front-End wie joblib , wie in Dougs Beitrag erwähnt. Die Standardbibliothek wird nicht verschwinden und wird gewartet, sodass das Risiko gering ist.
Es gibt auch andere Optionen, wie Parallel Python und IPythons parallele Funktionen . Ein kurzer Blick auf Parallel Python lässt mich glauben, dass es dem Geist von parfor näher kommt, indem die Bibliothek Details für den verteilten Fall kapselt, aber die Kosten dafür sind, dass Sie ihr Ökosystem übernehmen müssen. Die Kosten für die Verwendung von IPython sind ähnlich. Sie müssen die IPython-Methode anwenden, die es Ihnen wert sein kann oder nicht.
Wenn Ihnen der verteilte Speicher am Herzen liegt , empfehle ich mpi4py . Lisandro Dalcin leistet großartige Arbeit und mpi4py wird in den PETSc-Python-Wrappern verwendet. Wie Multiprocessing ist es eine Schnittstelle für Parallelität auf niedriger (er) Ebene als parfor, die jedoch wahrscheinlich eine Weile andauert.
quelle
Bevor ich nach einem "Black-Box" -Tool suche, mit dem parallele "generische" Python-Funktionen ausgeführt werden können, sollte analysiert werden, wie
my_function()
die Parallelisierung von Hand erfolgen kann.Vergleichen Sie zuerst die Ausführungszeit mit
my_function(v)
demfor
Overhead von Python- Schleifen: [C] Python-for
Schleifen sind ziemlich langsam, sodass der Zeitaufwandmy_function()
vernachlässigbar sein kann.Zweite Prüfung, ob es eine einfache Vektorimplementierung gibt
my_function(v)
, die keine Schleifen erfordert:F[:] = my_vector_function(X)
(Diese beiden ersten Punkte sind ziemlich trivial, verzeihen Sie mir, wenn ich sie hier nur der Vollständigkeit halber erwähnte.)
Der dritte und wichtigste Punkt ist, zumindest für CPython-Implementierungen, zu prüfen, ob die
my_function
meiste Zeit innerhalb oder außerhalb der globalen Interpretersperre oder GIL verbracht wird . Wenn Zeit außerhalb der GIL verbracht wird, sollte dasthreading
Standardbibliotheksmodul verwendet werden. ( Hier ein Beispiel). Übrigens könnte man sich das Schreibenmy_function()
als C-Erweiterung vorstellen, nur um die GIL zu veröffentlichen.Wenn
my_function()
die GIL nicht freigegeben wird, kann dasmultiprocessing
Modul verwendet werden .Referenzen: Python-Dokumentation zur gleichzeitigen Ausführung und Numpy / Scipy-Einführung zur parallelen Verarbeitung .
quelle
Du kannst es mit Julia versuchen. Es ist ziemlich nah an Python und hat viele MATLAB-Konstrukte. Die Übersetzung hier ist:
Dadurch werden auch die Zufallszahlen parallelisiert und die Ergebnisse am Ende während der Reduktion nur verkettet. Das nutzt Multiprocessing (Sie müssen also
addprocs(N)
vor der Verwendung Prozesse hinzufügen, und dies funktioniert auch auf mehreren Knoten auf einem HPC, wie in diesem Blogbeitrag gezeigt ).Sie können
pmap
stattdessen auch Folgendes verwenden:Wenn Sie Thread-Parallelität wünschen, können Sie verwenden
Threads.@threads
(stellen Sie jedoch sicher, dass Sie den Algorithmus thread-sicher machen). Legen Sie vor dem Öffnen von Julia die Umgebungsvariable JULIA_NUM_THREADS fest.Hier erstelle ich für jeden Thread ein separates Array, damit sie beim Hinzufügen zum Array nicht in Konflikt geraten und die Arrays anschließend einfach verketten. Threading ist ziemlich neu, daher gibt es im Moment nur die direkte Verwendung von Threads, aber ich bin sicher, dass Thread-Verkleinerungen und Maps genauso hinzugefügt werden, wie es für die Mehrfachverarbeitung war.
quelle
Ich empfehle, die parallelen und verzögerten Funktionen der JobLib-Bibliothek zu verwenden. Verwenden Sie das Modul "tempfile", um temporären gemeinsamen Speicher für große Arrays zu erstellen. Beispiele und Verwendung finden Sie unter https://pythonhosted.org/joblib/parallel.html
quelle