Ich habe eine große spärliche Matrix X im Format scipy.sparse.csr_matrix, und ich möchte dies mit einem numpigen Array W multiplizieren, das Parallelität nutzt. Nach einigen Recherchen habe ich entdeckt, dass ich Array im Multiprocessing verwenden muss, um zu vermeiden, dass X und W zwischen Prozessen kopiert werden (zB hier: Wie Pool.map mit Array (Shared Memory) in Python Multiprocessing? und Wird Shared Readonly-Daten in verschiedenen Prozessen für Python-Multiprozessing kopiert? ). Hier ist mein letzter Versuch
%Vor%Die Ausgabe ist jedoch etwas wie: (4.431, 0.165), was anzeigt, dass die parallele Version viel langsamer ist als die nicht parallele Multiplikation.
Ich glaube, dass Verlangsamung in ähnlichen Situationen verursacht werden kann, wenn man große Daten in die Prozesse kopiert, aber dies ist hier nicht der Fall, da ich Array zum Speichern der gemeinsamen Variablen verwende (außer in numpy.frombuffer oder beim Erstellen) eine csr_matrix, aber dann konnte ich keine Möglichkeit finden, eine csr_matrix direkt zu teilen). Eine andere mögliche Ursache für die langsame Geschwindigkeit ist das Zurückgeben eines großen Ergebnisses jeder Matrixmultiplikation für jeden Prozess, aber ich bin mir nicht sicher, ob es einen Weg dafür gibt.
Kann jemand sehen, wo ich falsch liege? Danke für jede Hilfe!
Update: Ich kann nicht sicher sein, aber ich denke, große Datenmengen zwischen Prozessen zu teilen, ist einfach nicht so effizient, und idealerweise sollte ich Multithreading verwenden (obwohl die Global Interpreter Lock (GIL) das sehr schwer macht). Eine Möglichkeit ist es, die GIL mit Cython zu veröffentlichen (siehe Ссылка ), obwohl eine Menge davon die anzahl Funktionen müssen durch die GIL gehen.
Am besten ist es, mit Cython zu C zu wechseln. Auf diese Weise können Sie die GIL schlagen und OpenMP verwenden. Ich bin nicht überrascht, dass das Multiprocessing langsamer ist - da ist viel Overhead drin.
Hier ist ein naive Wrapper-OpenMP-Wrapper von CSparse's spärlicher Matrix - Vektor-Produktcode in Python.
Auf meinem Laptop läuft das ein bisschen schneller als scipy. Aber ich habe nicht so viele Kerne. Der Code, einschließlich des Skripts setup.py und der C-Header-Dateien und Zeug, befindet sich in folgendem Sinn: Ссылка
Ich vermute, dass Sie, wenn Sie wirklich wollen, dass der parallele Code schnell ist (auf meinem Laptop ist er nur etwa 20% schneller als single-threaded scipy, auch wenn Sie 4 Threads verwenden), müssen Sie genauer darüber nachdenken, wo die Parallelität passiert, als ich es tat, auf die Cache-Lokalität achten.
%Vor%Es ruft einige C von CSparse.
%Vor%Vielleicht ein bisschen spät mit der Antwort. Mit dem Paket pyTrilinos, das Python-Wrapper für viele Funktionen in Trilinos zur Verfügung stellt, ist es möglich, zuverlässige parallele Beschleunigungen zu erhalten. Hier ist Ihr Beispiel für die Verwendung von pyTrilinos konvertiert:
%Vor%Sie können diesen Code dann mit MPI
ausführen %Vor%Weitere Beispiele für PyTrilinos finden Sie im github-Repository hier . Natürlich, wenn man pyTrilinos verwenden würde, wäre diese Art, die Matrix mit scipy zu initialisieren, möglicherweise nicht optimal.
Tags und Links python parallel-processing sparse-matrix scipy