Klassenfrage :)
-
@Th69 sagte in Klassenfrage :
@EL-europ sagte in Klassenfrage :
...
Ich meinte damit hauptsächlich dein Verständnis bzgl. der Speicherallokationen und -zugriffe.
Und ich hatte dir doch den Link zu C++std::thread
gegeben - dann mach dich mal darüber schlau...Das ich in c++ rohe c-array benötige ist vielleicht schwach, aber wo liegt der Fehler?
-
Ich habe gerade mal in dein Makefile geguckt. Du scheint immer noch keine Optimierungsflags zu nutzen. Das solltest du immer machen, z.b.
-O2
: https://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html
Das ist viel wichtiger, als zu versuchen manuell mit mehreren Threads irgendwie die Performance zu optimieren.memcpy
kopiert einen zusammenhängenden Speicherblock, deine Matrix ist aber kein zusammenhängender Block, sondern ein Array, in dem jeder Eintrag auf einen anderen Block zeigt.Hier im Forum gibt es irgendwo einen Thread, in dem sehr gute erklärt wird, wie man eine Matrix Klasse in C++ programmieren würde, damit man (x, y) Zugriff hat, aber trotzdem den Speicher direkt im Block vorliegen hat, was auch aus Performance Gründen Vorteile hat.
Wenn du den Malloc Teil weglassen würdest, und zum Beispiel einfach mit
std::vector<std::vector<int>>
arbeiten würdest, wären es immer noch kein zusammenhängender Speicherblocke und es ging schöner, aber du bräuchtest keinmalloc
keinfree
und einzelne Komponenten kopieren würde einfach so funktionieren, wie du es erwarten würdest.
-
@Schlangenmensch sagte in Klassenfrage :
Ich habe gerade mal in dein Makefile geguckt. Du scheint immer noch keine Optimierungsflags zu nutzen. Das solltest du immer machen, z.b.
-O2
: https://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html
Das ist viel wichtiger, als zu versuchen manuell mit mehreren Threads irgendwie die Performance zu optimieren.memcpy
kopiert einen zusammenhängenden Speicherblock, deine Matrix ist aber kein zusammenhängender Block, sondern ein Array, in dem jeder Eintrag auf einen anderen Block zeigt.Hier im Forum gibt es irgendwo einen Thread, in dem sehr gute erklärt wird, wie man eine Matrix Klasse in C++ programmieren würde, damit man (x, y) Zugriff hat, aber trotzdem den Speicher direkt im Block vorliegen hat, was auch aus Performance Gründen Vorteile hat.
Wenn du den Malloc Teil weglassen würdest, und zum Beispiel einfach mit
std::vector<std::vector<int>>
arbeiten würdest, wären es immer noch kein zusammenhängender Speicherblocke und es ging schöner, aber du bräuchtest keinmalloc
keinfree
und einzelne Komponenten kopieren würde einfach so funktionieren, wie du es erwarten würdest.Die colormatrix schreibe ich ja auch entsprechend ihres Aufbaus in den fbspiegel den ich dann mit memcpy ins Devicefile kopiere. Da liegt der Fehler nicht und es funktioniert ja ohne die Sanitizer bis auf die Meldung, das er die Breite des Wertes einer arithmetischen Operation nicht kennt, in der Thread-Funktion.
-
@EL-europ sagte in Klassenfrage :
Das ich in c++ rohe c-array benötige ist vielleicht schwach, aber wo liegt der Fehler?
Sorry, aber das Kernproblem liegt daran dass du auf Ratschläge anderer nicht hörst und vor allen Dingen du dich nicht weiterbildest und Sachen prüfst.
Sehr viele Sachen in der Informatik lassen sich beweisen. So auch die Aussage "Du kannst nicht einfach ein per Doppelzeiger angelegtes Array (int** matrix) sequentiell kopieren"
Eine kleines Prüfprogramm ergäbe dann folgendes:
#include <stdlib.h> #include <stdio.h> // Testprogramm int main() { int xres = 5; int yres = 5; int **matrix = (int**)malloc(xres * sizeof(int*)); for (int i = 0; i < xres; i++) matrix[i] = (int*)malloc(yres * sizeof(int)); int Count = 0; for (int x = 0; x < xres; x++) { for (int y = 0; y < yres; y++) { matrix[x][y] = Count++; } } // memcpy greift sequenziell zu, also gebe ich diese mal sequenziell aus int* P = matrix; //int* P = *matrix; for (int i = 0; i < xres * yres; i++) { printf("%i ", *P); if (i % xres == 0 && i != 0) printf("\n"); P++; } return 0; }
-
@Quiche-Lorraine memcpy schreibt nur den fbspiegel ins Devicefile, putSpiegel und putDevice übersetzen die Matrizen
-
memcpy(matrix, thr_matrix, paras.xres*paras.yres*sizeof(int));
Von hier: https://github.com/momefilo/mandelbrodt/blob/main/include/_Apple.cpp
-
@Schlangenmensch
Ah mom das Funktioniert also nur weil er zufällig zusammenhängenden Speicher alloziert? Oder wo ist das prop?
die matrix ist ja std::vector und die thr_matrix ein rohes array, ist dort ein pproblem?
-
@EL-europ Es "funktioniert" gar nicht. Du kopierst
paras.xres*paras.yres*sizeof(int)
Bytes vonthr_matrix[0][0]
beginnend nachmatrix[0][0]
.
Wenn dir der Speicher gehört, wird das kopiert was da drinnen steht. Wenn dir der Speicher nicht gehört, macht vermutlich dein Programm nen Abflug.In dem Code der im Github ist gibt es an der Stelle keinen
std::vector
, das ist einint **matrix;
siehe (https://github.com/momefilo/mandelbrodt/blob/main/include/_Apple.h)
-
@Schlangenmensch
ich muss wohl warten bis ich mir ein neues Buch Kaufe und die Ganze Thread-Funktion im sauberem c++ hinzubekommen. so das dort die c-arrays überflüssig werden. Denn wenn ich darüber iterieren muss um zu kopieren geht mir der Vorteil durch die threads zum Teil zumindest wieder verloren
-
@Schlangenmensch
Ja genau die matrix hab ich ja deswegen als solches definiert, also wo soll da das Problem sein?
Das ist kein Lehrbuchcode aber er läuft auf meinem Raspi5, nach dem beheben des groben Schnitzers, bei mir einwandfreiBin grad wieder am Funktionen hizufügen weil ich sonst nichts mit dem Code machen kann ohne neues Buch. Und die Funktionen sind einfach ohne Threads, dazu reicht mir Internet
-
@EL-europ sagte in Klassenfrage :
Ah mom das Funktioniert also nur weil er zufällig zusammenhängenden Speicher alloziert? Oder wo ist das prop?
Führe doch mal das Beispiel aus! Ist nicht schwer und beisst dich nicht! Aber der Erkenntnisgewinn wird groß werden!
-
@EL-europ sagte in Klassenfrage :
Das ist kein Lehrbuchcode aber er läuft auf meinem Raspi5, nach dem beheben des groben Schnitzers, bei mir einwandfrei
Kennst du nicht den Programmieren-Witz: "Es kompiliert (bzw. funktioniert) bei mir, ich kann ausliefern"?
Welchen groben Schnitzer meinst du jetzt?
-
@Th69
Das Freigeben des zu vor allozierten speichers um wieder neuen unter der selben Variable zu allozieren, in Apple->calc() für die lokalen rohen c-arrays
-
@Quiche-Lorraine
Führe doch mal das Beispiel aus! Ist nicht schwer und beisst dich nicht! Aber der Erkenntnisgewinn wird groß werden!
er kopiert den inhalt beginnend der start adressen
Es sind ja beides rohe c-arrays
-
@EL-europ sagte in Klassenfrage :
er kopiert den inhalt beginnend der start adressen
Es sind ja beides rohe c-arraysOk, du möchtest keine Hilfe.
Und Tschüss..
-
@EL-europ
Es kann zufällig funktionieren. Es kann blödsinn ausgeben. Es kann abstürzen. Der Code ist einfach inhaltlich falsch, auch wenn es kompiliert und ausgeführt wird.int** matrix = (int**)malloc(xres * sizeof(int*)); for (int i = 0; i < xres; i++) matrix[i] = (int*)malloc(yres * sizeof(int)); int Count = 0; for (int x = 0; x < xres; x++) { for (int y = 0; y < yres; y++) { matrix[x][y] = Count++; } } int** matrix2 = (int**)malloc(xres * sizeof(int*)); for (int i = 0; i < xres; i++) matrix2[i] = (int*)malloc(yres * sizeof(int)); memcpy(matrix2, matrix, xres * yres * sizeof(int)); //int* P = *matrix; for (int x = 0; x < xres; x++) { for (int y = 0; y < yres; y++) { printf("%i ", matrix2[x][y]); } printf("\n"); } free(matrix); free(matrix2);
Führe das 10 mal aus. Kann gut gehen, muss aber nicht.
int main() { int xres = 5; int yres = 5; for (int z = 0; z < 10; ++z) { int** matrix = (int**)malloc(xres * sizeof(int*)); for (int i = 0; i < xres; i++) matrix[i] = (int*)malloc(yres * sizeof(int)); int Count = 0; for (int x = 0; x < xres; x++) { for (int y = 0; y < yres; y++) { matrix[x][y] = Count++; } } int** matrix2 = (int**)malloc(xres * sizeof(int*)); for (int i = 0; i < xres; i++) matrix2[i] = (int*)malloc(yres * sizeof(int)); memcpy(matrix2, matrix, xres * yres * sizeof(int)); //int* P = *matrix; for (int x = 0; x < xres; x++) { for (int y = 0; y < yres; y++) { printf("%i ", matrix2[x][y]); } printf("\n"); } free(matrix); free(matrix2); } return 0; }
Schleife drum rum, und noch keinen Durchlauf hinbekommen bei dem das passiert wäre, was du hoffst.
-
@EL-europ: Abschließend von mir noch ein paar Hinweise.
Nur die Freigabe vonmatrix
reicht auch nicht aus, denn du hast ja mehrfachemalloc
-Aufrufe (eben explizit für jedenmatrix[i]
), so daß du auch diese freigeben mußt (zu jedemmalloc
-Aufruf gehört ein zugehörigesfree
).
Du kannst dir auch mal diese Werte (matrix
,matrix[i]
) ausgeben lassen.
Vielleicht bringt dich das auf die wichtige Erkenntnis.Und am besten ist es auch, du erzeugst dir viele einzelne Testprogramme (gerade um C++ auch zu verstehen) bzw. nutzt ein Test-Framework (wie z.B. Google Test). Diese kannst du auch dann auf deinem Entwicklungssystem ausführen (anstatt auf dem RASPI).
Dann wirst du auch erkennen, daß du dein Programm anders strukturieren solltest - auch damit du Fehler selber besser und schneller identifizieren kannst.Edit:
Hier noch der Link zu einer 2D-Array Klasse für C++: Array2D: Evolution von manueller Speicherverwaltung zur STL
-
int main(){ int xres=10; int yres=10; for(int count=0; count<1000; count++){ int **thr_matrix = (int**)malloc(xres * sizeof(int*)); for(int i=0; i<xres; i++){ thr_matrix[i] = (int*)malloc(yres * sizeof(int)); } int **matrix = (int**)malloc(xres * sizeof(int*)); for(int i=0; i<xres; i++){ matrix[i] = (int*)malloc(yres * sizeof(int)); } int z = 0; for(int x=0; x<xres; x++){ for(int y=0; y<yres; y++){ thr_matrix[x][y] = z++; } } memcpy(matrix, thr_matrix, (xres*yres)*sizeof(int)); for(int x=0; x<xres; x++){ for(int y=0; y<yres; y++){ if(matrix[x][y] != thr_matrix[x][y]){ printf("matrix[x][y]=%d, thr_matrix[x][y]=%d\n", matrix[x][y], thr_matrix[x][y]); printf("count %d\n", count); } } } free(matrix); free(thr_matrix); } }
Beim compilieren meckert er:
test.cpp: In function ‘int main()’:
test.cpp:38:23: warning: ‘void* memcpy(void*, const void*, size_t)’ writing 400 bytes into a region of size 80 overflows the destination [-Wstringop-overflow=]
38 | memcpy(matrix, thr_matrix, (xres*yres)*sizeof(int));
|~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^
test.cpp:28:45: note: destination object of size 80 allocated by ‘malloc’
28 | int matrix = (int)malloc(xres * sizeof(int*));Da hat der Compiler doch vergessen das ich noch yres-mal thr_matrix[i] alloziiert habe? oder?
Bei mir macht das prog hier keine Ausgabe, also alles ok?
-
@EL-europ sagte in Klassenfrage :
Da hat der Compiler doch vergessen das ich noch yres-mal thr_matrix[i] alloziiert habe? oder?
Sorry, aber was ist wohl wahrscheinlicher:
a) du hast den Code nicht verstanden
b) der Compiler hat etwas vergessen (und noch dazu in einem Beispiel, das extra für dich für dein Verständnisproblem erstellt wurde)Bei mir macht das prog hier keine Ausgabe, also alles ok?
Im Programm von @Schlangenmensch ist ein printf drin. Wenn dann keine Ausgabe kommt, ist alles ok? Da die Datei bei dir
test.cpp
heißt: du führst nicht zufällig das shell-builtintest
aus?
-
@wob
Lies den Code!