Ich versuche derzeit, grundlegende Matrixvektormultiplikation in Cython (als Teil einer viel größeres Projekt, um die Berechnung zu reduzieren ) und feststellen, dass mein Code etwa 2x langsamer ist als Numpy.dot
.
Ich frage mich, ob es etwas gibt, was ich vermisse, was zur Verlangsamung führt. Ich schreibe optimierten Cython-Code, deklariere Variablentypen, benötige zusammenhängende Arrays und vermeide Cache-Misses. Ich habe sogar versucht, Cython als Wrapper zu verwenden und nativen C-Code aufzurufen (siehe unten).
Ich frage mich: Was könnte ich noch tun, um meine Implementierung zu beschleunigen, so schnell wie NumPy für diese grundlegende Operation?
Der Cython-Code, den ich verwende, ist beow:
%Vor% Ich kompiliere diese Datei ( seMatrixVectorExample.pyx
) mit dem folgenden Skript:
und verwenden Sie das folgende Testskript, um die Leistung zu bewerten:
%Vor% Für eine Testmatrix mit n_rows = 10e6
und n_cols = 100
bekomme ich:
Bearbeiten: Es ist erwähnenswert, dass die Verlangsamung auch dann anhält, wenn ich die Matrixmultiplikation in nativem C-Code implementiere und Cython nur als Wrapper verwende.
%Vor% und hier ist der Cython-Wrapper, der den Zeiger nur an das erste Element von y
, A
und x
sendet. :
OK hat endlich Laufzeiten erreicht, die besser sind als NumPy!
Hier ist, was (ich denke) den Unterschied verursacht: NumPy ruft BLAS-Funktionen auf, die in Fortran statt C codiert sind, was zu der Geschwindigkeitsdifferenz führt.
Ich denke, dass dies wichtig ist, da ich zuvor den Eindruck hatte, dass die BLAS-Funktionen in C codiert waren und nicht sehen konnten, warum sie merklich schneller liefen als die zweite native C-Implementierung, die ich in der Frage gepostet habe.
In beiden Fällen kann ich die Leistung replizieren, indem ich Cython + die SciPy Cython BLAS-Funktionszeiger von scipy.linalg.cython_blas.
Der Vollständigkeit halber ist hier der neue Cython-Code blas_multiply.pyx
:
Hier ist der Code, den ich zum Erstellen verwende:
%Vor% Und hier ist der Testcode (beachten Sie, dass Arrays, die an die BLAS-Funktion übergeben werden, jetzt F_CONTIGUOUS
sind)
Das Ergebnis dieses Tests auf meiner Maschine ist:
%Vor%Tags und Links python linear-algebra numpy cython matrix