Fungerar va_arg med float* ?
Re: Fungerar va_arg med float* ?
Jag tror det ska gå att titta på adressen av en variabel.
Om du stannar med debuggern i en funktion, väljer en variabel och ser adressen på den.
Om det räknar går från noll eller vad det går från, så kan man se var den ligger och få ett hum om minnesförbrukning upp till den variabeln.
Om du stannar med debuggern i en funktion, väljer en variabel och ser adressen på den.
Om det räknar går från noll eller vad det går från, så kan man se var den ligger och få ett hum om minnesförbrukning upp till den variabeln.
Re: Fungerar va_arg med float* ?
Nu vet jag inte vilken precision dina beräkningar kräver men float16 eller bfloat16 kanske skulle kunna vara något för dig.
Re: Fungerar va_arg med float* ?
Jag hittade problemet. Minnet tog slut.hawkan skrev: ↑13 februari 2025, 12:37:24 Jag tror det ska gå att titta på adressen av en variabel.
Om du stannar med debuggern i en funktion, väljer en variabel och ser adressen på den.
Om det räknar går från noll eller vad det går från, så kan man se var den ligger och få ett hum om minnesförbrukning upp till den variabeln.
Precisionen är 0.001.
Vet du vad som är mest optimalt för optimeringsflaggorna -Oz eller -Os?
Indexera en array igenom absolut indexering [i * column + j] eller flytta indexnollan på arrayen?
Re: Fungerar va_arg med float* ?
Det tar du reda på genom att mäta med de olika inställningarna.
Re: Fungerar va_arg med float* ?
Nu fungerar det!
672 bytes allokerar jag för den kvadratiska programmeringen!
Nu är nästa problem att öka hastigheten!
Edit:
Är det någon som vill lära sig MPC? Det är som PID, fast bättre på alla punkter, förutom hastighet. MPC används när störningar eller dötider är kända.

672 bytes allokerar jag för den kvadratiska programmeringen!
Nu är nästa problem att öka hastigheten!
Edit:
Är det någon som vill lära sig MPC? Det är som PID, fast bättre på alla punkter, förutom hastighet. MPC används när störningar eller dötider är kända.
Re: Fungerar va_arg med float* ?
Så där! Då var hastigheten ökad! 0.476 sekund per iteration....
Men den räknar ut samma resultat på mikrokontrollern, som på min dator. Trots olika kompilatorer.
Men den räknar ut samma resultat på mikrokontrollern, som på min dator. Trots olika kompilatorer.
Re: Fungerar va_arg med float* ?
Följer kompilatorerna samma standard ska resultat bli exakt samma!
Re: Fungerar va_arg med float* ?
du borde inte få varken slut på minne eller få särskilt mycket heap fragmentation
speciellt inte om du kör med exakt det programmet som angivits
och de #defines
samt bara en gång
det kan också vara "undefined behaviour" att göra return på main funktion i MCU sammanhang
så bäst är att göra en vanlig while(1) {} istället när du kör koden på MCU
ska gå att göra:
alltså när man använder variadic så försvinner const
så det är ganska meningslöst att använda det på funktionsanropets parametrar
här är ett omskrivning ifrån chatgpt (som är baserad på ett påstående som jag trodde på och är tydligen fel):
i jämförelse med gcc så det kan vara någon matchningsfel där som optimeras bort
så
ska vara
efterssom följande inte är const och kan inte heller vara det:
Anropet kan göras utan const eftersom de ändå ignoreras i variadic-funktionen.
här är en lista på övriga varningar:
att const float t inte används innebär också att den inte behövs i rk4args heller
men det kan ju vara så att du använder den när du använder andra callbacks så kanske bäst är att låta dem vara
För övrigt hade inte printf fungerat utan variadic, åtminstone inte lika dynamiskt som det gör nu.
kan ju hålla med om att man borde använda dynamisk allokering så lite som möjligt
(men att helt undvika det gör det mycket svårt att tex tillåta dynamiska filer som innehåller dynamisk konfigurering samt inläsning och tolkning av runtime scripts)
i min begynnelse av mcu så användes pic16f877 så där var inget alternativ och jag använde ren c samt assembly
håller på med ett relativt stort projekt nu och det är ganska svårt att få chatGPT att undvika att använda std::stack samt std::vector
den tjatar också om att använda smarta pekare vilket jag helst inte vill då jag i detta fall vill ha full kontrol på vad som händer utan att gräva för mycket i c++
samt vill undvika onödigheter.
Jag kommer göra ett inlägg om det projektet ganska snart, men exakt när är inte bestämt.
speciellt inte om du kör med exakt det programmet som angivits
och de #defines
samt bara en gång
det kan också vara "undefined behaviour" att göra return på main funktion i MCU sammanhang
så bäst är att göra en vanlig while(1) {} istället när du kör koden på MCU
ska gå att göra:
Kod: Markera allt
#ifdef _MSC_VER
// Kör på MSVC
return EXIT_SUCCESS;
#else
// Kör på andra kompilatorer (t.ex. GCC på ARM)
while(1) {} // loopar oändligt istället för att returnera
#endif
alltså när man använder variadic så försvinner const
så det är ganska meningslöst att använda det på funktionsanropets parametrar
här är ett omskrivning ifrån chatgpt (som är baserad på ett påstående som jag trodde på och är tydligen fel):
det verkar också som så att mvcc är mera tillåtande, alltså matchningen mellan argumenten och när man sedan använder va_argconst är ett 'promise' som anger att en variabel inte får ändras.
Kompilatorn använder det både för att varna vid försök till skrivning och för optimeringar.
Att casta bort const för att skriva till en sådan variabel är undefined behavior — det kan ibland fungera på vissa plattformar,
men kan också ge krascher eller oväntade värden, särskilt på system med read-only memory.
Man kan alltså inte lita på att skrivning via en sådan cast är säker.
i jämförelse med gcc så det kan vara någon matchningsfel där som optimeras bort
så
Kod: Markera allt
rows[i] = va_arg(args, const size_t);
columns[i] = va_arg(args, const size_t);
Kod: Markera allt
rows[i] = va_arg(args, size_t);
columns[i] = va_arg(args, size_t);
Kod: Markera allt
size_t* rows;
size_t* columns;
Kod: Markera allt
rk4args(ITERATIONS, h, Y, y0, N, odefun, number_of_pointers, A, (size_t)row_a, (size_t)column_a, B, (size_t)row_b, (size_t)column_b, u, (size_t)row_u, (size_t)column_u);
här är en lista på övriga varningar:
Kod: Markera allt
C:\TestFörProgram\VariadicEF>gcc -Wall -Wextra -Wformat -Werror main.c
main.c: In function 'odefun':
main.c:196:12: error: unused variable 'column_U' [-Werror=unused-variable]
196 | size_t column_U = columns[2];
| ^~~~~~~~
main.c:195:12: error: unused variable 'row_U' [-Werror=unused-variable]
195 | size_t row_U = rows[2];
| ^~~~~
main.c:184:25: error: unused parameter 't' [-Werror=unused-parameter]
184 | void odefun(const float t, float y[], float* matrices[], const size_t rows[], const size_t columns[]) {
| ~~~~~~~~~~~~^
cc1.exe: all warnings being treated as errors
men det kan ju vara så att du använder den när du använder andra callbacks så kanske bäst är att låta dem vara
För övrigt hade inte printf fungerat utan variadic, åtminstone inte lika dynamiskt som det gör nu.
kan ju hålla med om att man borde använda dynamisk allokering så lite som möjligt
(men att helt undvika det gör det mycket svårt att tex tillåta dynamiska filer som innehåller dynamisk konfigurering samt inläsning och tolkning av runtime scripts)
i min begynnelse av mcu så användes pic16f877 så där var inget alternativ och jag använde ren c samt assembly
håller på med ett relativt stort projekt nu och det är ganska svårt att få chatGPT att undvika att använda std::stack samt std::vector
den tjatar också om att använda smarta pekare vilket jag helst inte vill då jag i detta fall vill ha full kontrol på vad som händer utan att gräva för mycket i c++
samt vill undvika onödigheter.
Jag kommer göra ett inlägg om det projektet ganska snart, men exakt när är inte bestämt.
Re: Fungerar va_arg med float* ?
Vackert! Tack så mycket.
Jag tror att jag till och med hade löst detta problem med float.
Kul med projekt! Jag fick denna algoritm att fungera på en liten mikrokontroller som räknar ut Kalman-Bucy filtret.
Jag tror att jag till och med hade löst detta problem med float.
Kul med projekt! Jag fick denna algoritm att fungera på en liten mikrokontroller som räknar ut Kalman-Bucy filtret.
Re: Fungerar va_arg med float* ?
Kul att du har valt att dyka in i mikrokontroller världen.
Ett par saker värda att tänka på, som flera tidigare pekat ut, är bland annat att helt utesluta användningen utav dynamiskt minne i inbäddade arkitekturer, även om det tekniskt sett funkar till viss del.
Du måste vända på sättet du tänker när det gäller minnesallokering. Dynamisk minnesallokering är en bra arkitektur på en PC med mycket minne där program körs parallelt på begäran utav användaren i en "best effort" strategi.
Om en dator får slut på minne så kan den tillfälligt flytta vissa delar utav minnet till hårddisken (paging) eller i värsta fall helt enkelt avsluta ditt program. En dator använder sig utav en virtuell minnesarkitektur där program alltid körs isolerade ifrån varandra och all minnesallokering (statisk och dynamisk) måste allokeras genom kerneln. En mikrontroller å andra sidan är framtagen främst för att vara så kostnadseffektiv och prestandaeffektiv som möjligt (SRAM ist för DRAM) där du bygger arkitekturen på ett deterministiskt sätt, både när det gäller körtid, minnesanvändning och interrupts.
Istället för att försöka hitta sätt att använda malloc, så designa om din arkitektur. Börja med att estimera hur mycket minne du kan allokera till dina uppgifter. I detta fallet om du har 8kb RAM så räkna med att du vill allokera iallafall 1.5kb till stacken (helt beroende på hur mycket du vill allokera på stacken och hur mycket du vill allokera statiskt samt hur djupt ditt program går). Allokera sedan variabler statiskt och gör dem så stora som du har råd med och räkna sedan ut hur många parametrar du kan skicka in som mest. Du kan se statisk minnesallokering i verktygen i CubeIDE. Nu har jag bara skummat igenom din kod men I ditt fall så har du antingen minnes fragmentering eller så har du konfigurerat en för liten heap storlek i STM32CubeIDE.
Ett par saker värda att tänka på, som flera tidigare pekat ut, är bland annat att helt utesluta användningen utav dynamiskt minne i inbäddade arkitekturer, även om det tekniskt sett funkar till viss del.
Du måste vända på sättet du tänker när det gäller minnesallokering. Dynamisk minnesallokering är en bra arkitektur på en PC med mycket minne där program körs parallelt på begäran utav användaren i en "best effort" strategi.
Om en dator får slut på minne så kan den tillfälligt flytta vissa delar utav minnet till hårddisken (paging) eller i värsta fall helt enkelt avsluta ditt program. En dator använder sig utav en virtuell minnesarkitektur där program alltid körs isolerade ifrån varandra och all minnesallokering (statisk och dynamisk) måste allokeras genom kerneln. En mikrontroller å andra sidan är framtagen främst för att vara så kostnadseffektiv och prestandaeffektiv som möjligt (SRAM ist för DRAM) där du bygger arkitekturen på ett deterministiskt sätt, både när det gäller körtid, minnesanvändning och interrupts.
Istället för att försöka hitta sätt att använda malloc, så designa om din arkitektur. Börja med att estimera hur mycket minne du kan allokera till dina uppgifter. I detta fallet om du har 8kb RAM så räkna med att du vill allokera iallafall 1.5kb till stacken (helt beroende på hur mycket du vill allokera på stacken och hur mycket du vill allokera statiskt samt hur djupt ditt program går). Allokera sedan variabler statiskt och gör dem så stora som du har råd med och räkna sedan ut hur många parametrar du kan skicka in som mest. Du kan se statisk minnesallokering i verktygen i CubeIDE. Nu har jag bara skummat igenom din kod men I ditt fall så har du antingen minnes fragmentering eller så har du konfigurerat en för liten heap storlek i STM32CubeIDE.