Sida 3 av 3

Re: Fungerar va_arg med float* ?

Postat: 13 februari 2025, 12:37:24
av hawkan
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.

Re: Fungerar va_arg med float* ?

Postat: 13 februari 2025, 12:53:01
av mankan
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* ?

Postat: 13 februari 2025, 14:23:23
av DanielM
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.
Jag hittade problemet. Minnet tog slut.
mankan skrev: 13 februari 2025, 12:53:01 Nu vet jag inte vilken precision dina beräkningar kräver men float16 eller bfloat16 kanske skulle kunna vara något för dig.
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* ?

Postat: 13 februari 2025, 14:31:46
av hawkan
Det tar du reda på genom att mäta med de olika inställningarna.

Re: Fungerar va_arg med float* ?

Postat: 15 februari 2025, 15:38:37
av DanielM
Nu fungerar det! :mrgreen:
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* ?

Postat: 15 februari 2025, 20:45:33
av DanielM
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.

Re: Fungerar va_arg med float* ?

Postat: 26 juli 2025, 19:12:37
av hummel
Följer kompilatorerna samma standard ska resultat bli exakt samma!

Re: Fungerar va_arg med float* ?

Postat: 28 juli 2025, 13:13:43
av DanielM
Det har jag ingen aning om.

Re: Fungerar va_arg med float* ?

Postat: 26 augusti 2025, 14:43:05
av manicken
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:

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):
const ä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.
det verkar också som så att mvcc är mera tillåtande, alltså matchningen mellan argumenten och när man sedan använder va_arg
i jämförelse med gcc så det kan vara någon matchningsfel där som optimeras bort


Kod: Markera allt

rows[i]     = va_arg(args, const size_t);
columns[i]  = va_arg(args, const size_t);
ska vara

Kod: Markera allt

rows[i]    = va_arg(args, size_t);
columns[i] = va_arg(args, size_t);
efterssom följande inte är const och kan inte heller vara det:

Kod: Markera allt

size_t* rows;
size_t* columns;
Anropet kan göras utan const eftersom de ändå ignoreras i variadic-funktionen.

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

Re: Fungerar va_arg med float* ?

Postat: 30 augusti 2025, 23:51:39
av DanielM
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.

Re: Fungerar va_arg med float* ?

Postat: 10 september 2025, 23:59:08
av Gaffel
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.