Was verursacht die 2x Verlangsamung in meiner Cython-Implementierung der Matrixvektormultiplikation?

8

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:

%Vor%

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:

%Vor%

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. :

%Vor%     
Berk U. 09.02.2016, 22:50
quelle

1 Antwort

3

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.

verwende

Der Vollständigkeit halber ist hier der neue Cython-Code blas_multiply.pyx :

%Vor%

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)

%Vor%

Das Ergebnis dieses Tests auf meiner Maschine ist:

%Vor%     
Berk U. 10.02.2016, 17:02
quelle