BOOST uBLAS-matrix-Produkt extrem langsam
Ist es ein Weg, um verbessern Sie die boost ublas-Produkt Leistung?
Ich habe zwei Matrizen A,B, das will ich mulitply/add/sub/...
In MATLAB vs. C++ bekomme ich folgende Zeiten [s] für eine 2000x2000 matrix-Operationen
OPERATION | MATLAB | C++ (MSVC10)
A + B | 0.04 | 0.04
A - B | 0.04 | 0.04
AB | 1.0 | 62.66
A'B' | 1.0 | 54.35
Warum es so einen enormen performance-Verlust hier?
Die Matrizen sind nur real verdoppelt.
Aber ich brauche auch positiv definites,symmetrischen,rechteckigen Produkten.
BEARBEITEN:
Der code ist trivial
matrix<double> A( 2000 , 2000 );
//Fill Matrix A
matrix<double> B = A;
C = A + B;
D = A - B;
E = prod(A,B);
F = prod(trans(A),trans(B));
EDIT 2:
Die Ergebnisse sind Mittelwerte von 10 trys. Die stddev war weniger als 0,005
Ich würde erwarten, dass ein Faktor 2-3 vielleicht, aber nicht 50 (!)
EDIT 3:
Alles war benched Release ( NDEBUG/MOVE_SEMANTICS/.. ) - Modus.
EDIT 4:
Feste Matrizen für die Produkt-Ergebnisse haben keinen Einfluss auf die Laufzeit.
- Werden Sie sicher, dass Sie eine saubere Matlab erneut ausführen, es neigt dazu, cache... gut, alles. Nicht vollständig, aber Sie sollten in der Lage sein, um menschenwürdige Leistung und eine einfache syntax von Eigen. (Ich bin interessiert wie es sich auf Ihren kleinen Maßstab, nur als kleiner Hinweis 🙂
- Ich würde erwarten, dass ~2000x Zeit, die für die Multiplikation vs dazu..
- Haben Sie daran gedacht, wiederum auf den release-Modus für uBlas. Siehe FAQ am Ende des [link=boost.org/doc/libs/1_47_0/libs/numeric/ublas/doc/..., die zeigen, dass Sie brauchen, um zu haben '-DNDEBUG' oder einige andere flags zu verursachen ublas zu kompilieren für die Freigabe.
- Sie nicht wissen, welche Rolle die Speicher-management ist, hier zu spielen.
prod
ist das zuweisen einer 32mb-matrix, und so isttrans
, zweimal, und dann tun alle, die 10 mal. Nehmen Sie ein paar stackhots und zu sehen, was es wirklich tut. Meine dumme Vermutung ist, wenn Sie vor der Zuordnung der Matrizen erhält man ein besseres Ergebnis. ublas
verwendet, expression templates, so preallocating ist nicht wahrscheinlich machen Dinge viel schneller, es sei denn, coder wird mutwillig verschwenden matrix kopiert (hier nicht der Fall).- Ich fand einige schöne benchmarks von den Leuten bei Eigen hier
- Siehe auch die Verwandte Frage (und Antworten) here. Insbesondere, versuchen Sie es mit axpy_prod.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Posten Sie Ihre C+ code für die Beratung über mögliche Optimierungen.
Sollten Sie sich jedoch bewusst, dass Matlab ist hoch spezialisiert für Ihre Aufgabe konzipiert, und Sie sind kaum in der Lage, um es anzupassen mit Boost. Auf der anderen Seite - Boost ist kostenlos, während Matlab entschieden nicht.
Ich glaube, dass am besten die Leistung Steigern können gehabt werden, indem die Bindung des uBlas-code, um eine zugrunde liegende LAPACK-Implementierung.
Sollten Sie verwenden
noalias
in der linken Seite der matrix-Multiplikationen, um loszuwerden, unnötige Kopien.Statt
E = prod(A,B);
verwendennoalias(E) = prod(A,b);
Aus der Dokumentation:
Gibt es viele effiziente BLAS-Implementierung, wie ATLAS, gotoBLAS, MKL, statt.
Ich nicht Holen, um den code, aber denke mal die ublas::prod(A, B) mit drei-loops, keine Blöcke und nicht cache-freundlich. Wenn das stimmt, prod(A, B, trans()) wird viel schneller als andere.
Wenn cblas ist verfügbar, mit cblas_dgemm, die für die Berechnung. Wenn nicht, können Sie einfach die Daten neu anordnen, bedeutet, prod(A, B, trans()) statt.
Sie nicht wissen, welche Rolle die Speicher-management ist, hier zu spielen.
prod
ist das zuweisen einer 32mb-matrix, und so isttrans
, zweimal, und dann tun alle, die 10 mal. Nehmen Sie sich ein paar stackhots und sehen, was es wirklich tun. Meine dumme Vermutung ist, wenn Sie vor der Zuordnung der Matrizen erhält man ein besseres Ergebnis.Andere Wege, matrix-Multiplikation, könnte beschleunigt werden, sind
pre-Umsetzung in der linken matrix, werden cache-freundlich, und
überspringt Nullen. Nur dann, wenn A(i,k) und B(k,j) sind beide nicht null, ist ein beliebiger Wert beigetragen.
Ob dies geschehen ist in uBlas ist anybody ' s guess.