Frage zur Speicherreservierung von 2 dim. Arrays
-
@manni66 sagte in Frage zur Speicherreservierung von 2 dim. Arrays:
@john-0
Wenn du eine std::vector benutzt hättest, hättest du die 3/5/0 Regel nicht verletzt."Gerüst" nicht gelesen? Der Rest der 3/5/0 Regel sei dem Leser überlassen.
-
@Jockelx
Ups, da fehlte operator()
-
@john-0 sagte in Frage zur Speicherreservierung von 2 dim. Arrays:
@manni66 sagte in Frage zur Speicherreservierung von 2 dim. Arrays:
@john-0
Wenn du eine std::vector benutzt hättest, hättest du die 3/5/0 Regel nicht verletzt."Gerüst" nicht gelesen? Der Rest der 3/5/0 Regel sei dem Leser überlassen.
Es gibt keinen Rest, wenn man nicht immer meint new/delete benutzen zu müssen.
-
@john-0 sagte in Frage zur Speicherreservierung von 2 dim. Arrays:
Ups, da fehlte operator()
Und das 'Matrix' ist nach wie vor zu viel.
Wobei mir auch überhaupt nicht klar ist, was das Ziel dieses fehlerhaften "Gerüst" sein soll.
-
@john-0 sagte in Frage zur Speicherreservierung von 2 dim. Arrays:
@It0101 sagte in Frage zur Speicherreservierung von 2 dim. Arrays:
Wenn ihr im C-Style rumspielen wollt, gibts da einen gesonderten Bereich für
Weder das eine noch das andere ergibt für Matrizen einen Sinn
Weil?
-
@Jockelx sagte in Frage zur Speicherreservierung von 2 dim. Arrays:
Wobei mir auch überhaupt nicht klar ist, was das Ziel dieses fehlerhaften "Gerüst" sein soll.
Reden wir über Matrizen und deren sinnvoller Nutzung in C++ oder geht es um möglichst schicken C++ Code? Der wesentliche Punkt bei Matrizen ist, dass man mit ihnen üblicherweise HPC macht und da keine der vorhanden Datenstrukturen in der STL wirklich für geeignet ist. Wenn man effizient Matrizrechnung machen muss, wird man auf so etwas wie die BLAS zurückgreifen müssen. Also ist ein ganz wesentlicher Aspekt, dass man kompatible Datenstrukturen verwendet. Denn von Hand eine Matrixmultiplikation zu schreiben, die mit der DGEMM z.B. MKL auch nur im Ansatz mithält, dürfte kaum möglich sein. Es gibt zwar Projekte, die die Funktionalität von BLAS und LAPACK rein als C++ Code umzusetzen versuchen, aber auch dann muss man sich mit den Datenstrukturen dieser Bibliotheken auseinandersetzen.
Die Frage ist daher wie speichert man sinnvoll die Daten einer Matrix in einem linearen Feld, so dass man darauf effizient zugreifen kann und diese Datenstruktur so gestaltet, dass sie z.B. von der vorhandenen BLAS genutzt werden kann. Wichtig dafür sind so Punkte wie Column Major vs. Row Major Order und Leading Dimension, weil das Dinge sind, die bei der BLAS nun einmal wichtig sind. Der ganze 0/3/5-Rule Kram ist zwar formalistisch wichtig, aber für das Problem Matrizen in C++ nur Beiwerk.
Zeiger auf Zeiger Strukturen oder noch schlimmer std::vector<std::vector<T>> sind zwar formalistisch korrekt, aber inkompatibel mit den BLAS Implementationen und nicht unbedingt die performanteste Lösung.
-
@manni66 sagte in Frage zur Speicherreservierung von 2 dim. Arrays:
Es gibt keinen Rest, wenn man nicht immer meint new/delete benutzen zu müssen.
Man muss aber auch nicht immer
std::vector
verwenden, speziell wenn man die Grösse schon kennt und nicht dynamisch ändern muss. In dem Fall dann lieberunique_ptr<T[]>
->2 * sizeof(void*)
weniger Overhead.
-
@john-0 sagte in Frage zur Speicherreservierung von 2 dim. Arrays:
und nicht unbedingt die performanteste Lösung.
Das mit der Performance ist klar. Aber weder hat der Threadersteller das Wort "Matrix" im Eingangspost verwendet, noch fiel in irgendeiner Form die Anforderung "performant".
Für mich war das nur ein typischer Anfängerthread, wo Hilfe gefragt war und kein "ich bin Doktor der Mathematik und will die Berechnung mit Matrizen revolutionieren, damit ich den Nobelpreis bekomme"-Thread.
-
Ein std::vector ist kompatibel mit C-Funtionen.
@john-0 sagte in Frage zur Speicherreservierung von 2 dim. Arrays:
Der ganze 0/3/5-Rule Kram ist zwar formalistisch wichtig, aber für das Problem Matrizen in C++ nur Beiwerk.
Das ist kein Beiwerk! Deine Matrixklasse erzeugt durch Kopieren UB.
-
@manni66 sagte in Frage zur Speicherreservierung von 2 dim. Arrays:
Ein std::vector ist kompatibel mit C-Funtionen.
@john-0 sagte in Frage zur Speicherreservierung von 2 dim. Arrays:
Der ganze 0/3/5-Rule Kram ist zwar formalistisch wichtig, aber für das Problem Matrizen in C++ nur Beiwerk.
Das ist kein Beiwerk! Deine Matrixklasse erzeugt durch Kopieren UB.
Volle Zustimmung. Die Rule of 0 besagt ja gerade, dass man dieses "Beiwerk" lieber dahin verschieben sollte, wo es hingehört. Wieso sollte eine Matrix Speicher verwalten? Das ist nicht ihre Aufgabe. Das hat gefälligst eine spezialisierte Speicherverwaltungsklasse zu übernehmen, die das dann auch richtig macht. Daher ist das wohl eine der wichtigsten Regeln in C++, kein Formalismus.
-
@SeppJ sagte in Frage zur Speicherreservierung von 2 dim. Arrays:
Volle Zustimmung. Die Rule of 0 besagt ja gerade, dass man dieses "Beiwerk" lieber dahin verschieben sollte, wo es hingehört. Wieso sollte eine Matrix Speicher verwalten? Das ist nicht ihre Aufgabe. Das hat gefälligst eine spezialisierte Speicherverwaltungsklasse zu übernehmen, die das dann auch richtig macht. Daher ist das wohl eine der wichtigsten Regeln in C++, kein Formalismus.
Der wichtigste Punkt überhaupt ist es, dass man Code möglichst wiederverwenden sollte und nicht Dinge implementiert, die andere deutlich besser gelöst haben. Die Frage bei einer Matrix Klasse ist nun was da schwerer wiegt, die Implementation der Speicherverwaltung oder die effiziente Umsetzung der Implementation von so Dingen wie die Matrizenmultiplikation. Wenn man sich das Paper von Goto und Geijn anschaut dürfte klar sein, was mehr Arbeit ist. D.h. die Speicherverwaltung ist das leichtere Problem.
Der wichtigste Aspekt bei dem hier geschilderten Problem ist, wie man eine Matrix auf linearen Speicher abbildet. Also wie berechnet man aus zwei Indexvariablen den korrekten Index für den Speicherzugriff? Das ist bei einer Matrix das Wichtigste. Bei C++ muss man damit auch über die Row Major Order (die kommt man bei den statischen zweidimensionalen Felder zum Einsatz) sprechen, sprich wie sind die Elemente im linearen Speicher angeordnet.
Weshalb sollte man in einer Matrix Klasse den Speicher selbst verwalten und kein std::vector nutzen? std::vector hat so einige Eigenschaften, die nicht unbedingt ideal für eine Matrix sind. std::array wäre, wenn es denn auf dem Heap angelegt würde und deine dynamische Größe haben könnte, die bessere Speicherklasse. So ist Matrix Klasse ähnlich fundamental anzusehen wie std::vector und müsste eigentlich Teil der Standardlibrary sein. Wenn es denn da nicht das Problem gäbe, dass in den letzten Revisionen der Standardlibrary immer mehr die Verwendung von Memory Allocatoren zu einem Problem geworden wäre, da sie nicht konsequent genutzt werden.
-
@manni66
Ich habe das Codebeispiel so angepasst, dass klar sein dürfte, dass das nur ein Gerüst ist in die Funktionalität implementiert werden muss. Akzeptabel?
-
@john-0 sagte in Frage zur Speicherreservierung von 2 dim. Arrays:
std::vector hat so einige Eigenschaften, die nicht unbedingt ideal für eine Matrix sind.
Nenn doch mal konkret einige, dieser einigen nicht idealen Eigenschaften.
-
Kleine Anmerkung: Für Matrizen in C++ kann ich EigenLib empfehlen, hat auch schon SIMD Optimierungen mit drin, und ist recht umfangreich, und einfach einzubinden.
-
Oder Blitz++
-
Schön, dass wir es von einer einfachen Anfänger-Frage zum Verlinken eines wissenschaftlichen Papers und einer Diskussion über Memory-Allokatoren geschafft haben... Das wird dem Threadersteller bestimmt weiterhelfen.
-
@It0101
Ist ja nicht so, dass am Anfang nicht auf die Frage eingegangen wurde. Was stört dich an einer Folgediskussion?