Wie kann denn C++ für Embedded genutzt werden, wenn dynamischer Speicher verboten ist? Ist es möglich C++ nur mit globalen Variablen zu nutzen? So wird ja dynamisch Speicher für eine Klassen-Instanz reserviert: GraphBox *graphbox = new GraphBox(...); Und so würde alternativ die Klassen-Instanz dynamisch auf den Stack kommen: int main(void) { ... GraphBox graphbox(...); ... } Aber die Klassen-Instanz graphbox als globale Variable geht nicht, oder? Der Konstruktor muss ja dynamisch ausgeführt werden. In C kann man natürlich für Structs machen: struct NODE { uint32_t data; struct NODE* prev; struct NODE* next; }; #define NODE_MAX 256 static struct NODE Node[NODE_MAX]; static uint32_t Node_idx = 0; static struct NODE *Node_malloc(void) { if (Node_idx < NODE_MAX) return &Node[Node_idx++]; else return NULL; } Wahrscheinlich müsste man in C++ new überladen mit ähnlich sowas: https://www.keil.com/support/man/docs/c51/c51_init_mempool.htm
> Aber die Klassen-Instanz graphbox als globale Variable geht nicht, oder? > Der Konstruktor muss ja dynamisch ausgeführt werden. Die Konstruktoren von globalen Instanzen werden vor main ausgeführt, in der Reihenfolge der Definition innerhalb eines C-Files - die Reihenfolge von verschiedenen C-Files ist nicht definiert.
foobar schrieb: >> Aber die Klassen-Instanz graphbox als globale Variable geht nicht, oder? >> Der Konstruktor muss ja dynamisch ausgeführt werden. > > Die Konstruktoren von globalen Instanzen werden vor main ausgeführt, in > der Reihenfolge der Definition innerhalb eines C-Files - die Reihenfolge > von verschiedenen C-Files ist nicht definiert. + Konstruktoren (und andere Methoden) möglichst constexpr machen, dann werden sie zu einem memcpy bei Programmstart. Statt new kann man evtl. auch placement-new verwenden (muss dann aber manuell die dtors aufrufen, weil man delete ja nicht verwenden kann)
foobar schrieb: > Die Konstruktoren von globalen Instanzen werden vor main ausgeführt Aber immer noch run-time, oder? Damit ist die Bedingung nicht erfüllt, dass der Compiler den verfügbaren Speicherplatz vorab prüfen kann wie in C z.B. Program Size: data=18.0 xdata=10 code=237
Lothar schrieb: > Aber die Klassen-Instanz graphbox als globale Variable geht nicht, oder? > Der Konstruktor muss ja dynamisch ausgeführt werden. Wieso muss der ctor "dynamisch" ausgefuehrt werden und warum denkst du das die Daten einer Klasse zwangsweise auf dem Heap liegen müssen? Die grösse der Instanz ist zur Kompilezeit klar, sonst wäre so was wie placement-new ja gar nicht nutzbar mit Klassen, ausser Exceptions und Allokatornutzende Dinge der STL gibt es keinen Heap Zwang in C++ d.h. aber schon das du dich schon stark einschränken musst
Wieso ist dynamischer Speicher verboten? Und ich benutze den auch, um dynamisch meine Objekte zu erzeugen. Funktioniert seit Jahren ohne Probleme. Was ich allerdings nicht mache ist die Objekte wieder frei zugeben. Oder innerhalb der Hauptschleife new und delete zu benutzen. Aber am Anfang die Dinge einmalig mit new zu initialisieren funktioniert prima.
Lothar schrieb: > Wie kann denn C++ für Embedded genutzt werden, wenn dynamischer Speicher > verboten ist? Es ist nicht grundsätzlich verboten, aber man versucht, es möglichst zu vermeiden. Je nach Anwendung kann es ggf. verboten sein. Und es gibt viele Anwendungen, wo dynamischer Speicher auch gar nicht nötig ist. Lothar schrieb: > foobar schrieb: >> Die Konstruktoren von globalen Instanzen werden vor main ausgeführt > > Aber immer noch run-time, oder? Kommt drauf an. Wenn sie constexpr sind oder vom Optimizer eliminiert werden, dann nicht. > Damit ist die Bedingung nicht erfüllt, dass der Compiler den verfügbaren > Speicherplatz vorab prüfen kann wie in C z.B. Was hat der Speicherplatz damit zu tun? Der ist ja schon da, wie bei jeder anderen globalen Variable auch. Der Konstruktor ist lediglich dazu da, aus einem vorhandenen "rohen" Speicherbereich durch Initialisierung der Membervariablen ein gültiges Objekt zu machen.
:
Bearbeitet durch User
Das Keyword heisst static Ein Weg wie sowas konsequent angewendet werden kann, ist hier zu finden: https://github.com/KonstantinChizhov/Mcucpp Als Beispiel beigefügt: ports_.h - mit meinen Modifikatonen: - Kommentare - table layout - SetBitwise, ClearBitwise: mit default template<reg=out, >
Rolf M. schrieb: > Was hat der Speicherplatz damit zu tun? Der ist ja schon da Kannst Du mal ein Beispiel zeigen wie man eine Klassen-Instanz als globale Variable deklariert?
Lothar schrieb: > Rolf M. schrieb: >> Was hat der Speicherplatz damit zu tun? Der ist ja schon da > > Kannst Du mal ein Beispiel zeigen wie man eine Klassen-Instanz als > globale Variable deklariert? Das sieht genau gleich aus wie bei einer lokalen Variable. Wenn man dein Beispiel hernimmt: Lothar schrieb: > int main(void) > { > ... > GraphBox graphbox(...); > ... > } Dann eben:
1 | GraphBox graphbox(...); |
2 | |
3 | int main(void) |
4 | {
|
5 | ...
|
6 | }
|
PittyJ schrieb: > Wieso ist dynamischer Speicher verboten? > Und ich benutze den auch, um dynamisch meine Objekte zu erzeugen. > Funktioniert seit Jahren ohne Probleme. Mit welchen µCs?
Udo S. schrieb: > PittyJ schrieb: >> Wieso ist dynamischer Speicher verboten? >> Und ich benutze den auch, um dynamisch meine Objekte zu erzeugen. >> Funktioniert seit Jahren ohne Probleme. > > Mit welchen µCs? Ich habe einen Arm M0 NXP LPC11 Und jetzt noch einen Arm M7 STM32H7 Da ich je nach Konfiguration der Peripherie mal dies oder das brauche, werden nur die benötigten Objekte mit new erzeugt.
Lothar schrieb: > Wie kann denn C++ für Embedded genutzt werden, wenn dynamischer Speicher > verboten ist? "Verboten" ist das falsche Wort. "Fehleranfällig" ist die Benutzung von dynamischem Speicher vor allem wenn dauernd reserviert und freigegeben wird. Dynamischer Speicher kann super genutzt werden, wenn man zum Beispiel nur bei Start dynamischen Speicher allokiert. Wird die Konfiguration geänert wird einfach alles neu gestartet und neu angelegt. Läuft seid Jahren in embedded Systemen ohne Probleme.
Klaus H. schrieb: > Lothar schrieb: >> Wie kann denn C++ für Embedded genutzt werden, wenn dynamischer Speicher >> verboten ist? > > "Verboten" ist das falsche Wort. > > "Fehleranfällig" ist die Benutzung von dynamischem Speicher vor allem > wenn dauernd reserviert und freigegeben wird. Was genau macht dynamischen Speicher im embedded Bereich fehleranfälliger?
mh schrieb: > Was genau macht dynamischen Speicher im embedded Bereich > fehleranfälliger? Zum Beispiel Speicherfragmentierung. Je kleiner der Speicher, desto problematischer wird diese. Da kann es passieren, dass trotz ausreichend freiem Speicher keiner mehr verfügbar ist, weil nicht am Stück. Und bei kritischen Funktionen will ich allgemein nicht, dass die Möglichkeit besteht, dass benötigter Speicher nicht allokiert werden kann. Man stelle sich ein ESP vor, dem bei einem Bremsmanöver der Speicher ausgeht. Deshalb nimmt man da lieber statischen Speicher, so dass es mit Sicherheit immer den nötigen Speicher hat.
mh schrieb: > Was genau macht dynamischen Speicher im embedded Bereich > fehleranfälliger? Nicht dynamischer Speicher allgemeinen, sondern die üblichen Implementierungen iin C/C++. Darum baut man sich embedded speziell angepassten dynamischen Speicher. Ring-Puffer, Message-Blöcke, priorisierte Zugriffsfunktionen. Es geht darum, in begrenzter Zeit einen Speicher zu bekommen, Fragmentierung zu vermeiden, Diagnose (wie viel frei, welche verloren, ...) Und zuerst unwichtige Dinge zu stoppen bzw. quasi getrennte "heaps" zu haben. Das erstmalige allokieren per new&co ist ok und sinnvoll, wenn es verschiedene Konfigurationen gibt und eine braucht diese Objekte, die andere jene. Allerdings ist dann meist ein Neustart notwendig wenn sie sich ändert.
> Was genau macht dynamischen Speicher im embedded Bereich > fehleranfälliger? Jedesmal wenn bei deinem Windows die Maus ruckelt weil das System mal wieder swapt oder ein verzweifeltes Programm ein Fenster auf macht um dir mitzuteilen das etwas nicht richtig geht, tja dann faehrt eine Embedded Steuerung vielleicht gerade eine 100kEuro teure Maschine gegen die Wand. Und die Wahrscheinlichkeit das solche Probleme bei einem Microcntroller mit 32k Ram auftreten ist groesser als bei einem Desktop mit 16GB. Olaf
Olaf schrieb: > tja dann faehrt eine > Embedded Steuerung vielleicht gerade eine 100kEuro teure Maschine gegen > die Wand. dagegen gibt es RTOS mit Prioritäten, eine Steuerungstask hat eine höhere Prio als das GUI. Und man kann mit Memory Pools arbeiten um auch dynamische Sachen zu entschärfen. Ethernet mit lwIP läuft z.B. so.
Johannes S. schrieb: > dagegen gibt es RTOS mit Prioritäten, eine Steuerungstask hat eine > höhere Prio als das GUI. Komplett anderes Thema. Wenn der dynamische Speicher alle ist, weil die GUI ein hübsches Icon geladen hat, bringt deiner Steuerungstask eine hohe Priorität auch nix mehr. > Und man kann mit Memory Pools arbeiten um auch dynamische Sachen zu > entschärfen. Ethernet mit lwIP läuft z.B. so. Klar gibt es Mittel, um trotzdem sicher mit dynamischem Speicher zu arbeiten. Aber diese müssen im ganzen Programm auch aktiv genutzt werden.
Rolf M. schrieb: > Zum Beispiel Speicherfragmentierung. Je kleiner der Speicher, desto > problematischer wird diese. Kannst du zeigen warum das allgemein so ist? Oder ist das vielleicht doch anwendungsspezifisch? Größe des Speichers, Größe , Häufigkeit und Verteilung der Allokationen, ... A. S. schrieb: > Nicht dynamischer Speicher allgemeinen, sondern die üblichen > Implementierungen iin C/C++. Ok das ist schonmal etwas ganz anderes ... A. S. schrieb: > [...] > Und zuerst unwichtige Dinge zu stoppen bzw. quasi getrennte "heaps" > zu haben. Du meinst, das was C++ von Haus aus eingebaut hat (allokator, pmr, ...)? Olaf schrieb: > Jedesmal wenn bei deinem Windows die Maus ruckelt weil das System mal > wieder swapt oder ein verzweifeltes Programm ein Fenster auf macht um > dir mitzuteilen das etwas nicht richtig geht, tja dann faehrt eine > Embedded Steuerung vielleicht gerade eine 100kEuro teure Maschine gegen > die Wand. Jedes mal wenn das bei mir auf dem HPC-Cluster, sind vielleicht ein paar millionen Stunden Rechenzeit verschwendet und ein mehrere millionen € Projekt in Verzug. Es geht auch in anderen Bereichen um viel Geld ... Olaf schrieb: > Und die Wahrscheinlichkeit das solche Probleme bei einem Microcntroller > mit 32k Ram auftreten ist groesser als bei einem Desktop mit 16GB. > > Olaf Bei dir vielleicht. Ich hab noch nie auf einem µC ein Problem mit dynamischen Speicher gehabt. Allerdings habe ich auf meinen Test Rechenknecht letzte Woche mehrfach einen OOM Fehler bekommen.
Rolf M. schrieb: > Klar gibt es Mittel, um trotzdem sicher mit dynamischem Speicher zu > arbeiten. Aber diese müssen im ganzen Programm auch aktiv genutzt > werden. Statisches Speichermanagment muss auch aktiv im ganzen Programm genutzt werden?
mh schrieb: >> "Fehleranfällig" ist die Benutzung von dynamischem Speicher vor allem >> wenn dauernd reserviert und freigegeben wird. > Was genau macht dynamischen Speicher im embedded Bereich > fehleranfälliger? Mein Satz war blöd formuliert, die nachfolgenden Beschreibungen eindeutiger. Ein Beispiel aus dem Leben: Ein PC Softwareentwickler sollte ein Messalgorithmus für ein Embedded System implementieren. Seine Lösung: In einem 1ms Interrupt wurde Speicher allokiert, eine Lookup Tabelle erstellt, Berechnungen durchgeführt, der Speicher wieder freigegeben. Dummerweise kam sich das ganze mit einem zweiten Interrupt (wieder mit Speicherallokierung) in die Quere. Alle paar Stunden war der Speicher so fragmentiert, dass "unerklärliche" Messwerte rauskamen. Dynamischer Speicher an sich ist nicht böse oder fehlerhaft. Seinen Einsatz ergibt einfach weitere Szenarien, die man kennen und berücksichtigen sollte. Auf PCs ggf verschmerzbar, in Autoairbags ggf schmerzerzeugbar.
mh schrieb: > Rolf M. schrieb: >> Klar gibt es Mittel, um trotzdem sicher mit dynamischem Speicher zu >> arbeiten. Aber diese müssen im ganzen Programm auch aktiv genutzt >> werden. > > Statisches Speichermanagment muss auch aktiv im ganzen Programm genutzt > werden? Nö, das erledigt der Linker. Ein Speichermanagement zur Laufzeit ist bei statischem Speicher nicht nötig.
Rolf M. schrieb: > Nö, das erledigt der Linker. Ein Speichermanagement zur Laufzeit ist bei > statischem Speicher nicht nötig. Wenn du so argumentierst ... bei mir erledigt das Speichermanagement die C++ Standardlib. Wenn du nicht über deinen statischen Speicher nachdenken musst, muss ich nicht über meinen dynamischen nachdenken.
Jetzt geht wieder die Schwarz / Weiss Sicht los. Es geht doch nicht um persönliche Vorlieben. Man muss einfach die kritischen Knackpunkte kennen.
Klaus H. schrieb: > Jetzt geht wieder die Schwarz / Weiss Sicht los. Es geht doch nicht um > persönliche Vorlieben. Man muss einfach die kritischen Knackpunkte > kennen. Exakt, es ist abhängig von der Anwendung, was die richtige Wahl ist.
mh schrieb: > Rolf M. schrieb: >> Nö, das erledigt der Linker. Ein Speichermanagement zur Laufzeit ist bei >> statischem Speicher nicht nötig. > > Wenn du so argumentierst ... Du hast mit der merkwürdigen Argumentation angefangen. > bei mir erledigt das Speichermanagement die C++ Standardlib. … deren Funktionen du dafür zur Laufzeit aufrufen musst, um den Speicher für deine Daten zu bekommen. Aber darum ging es eigentlich überhaupt nicht. Es ging um diese Aussage: Johannes S. schrieb: > Und man kann mit Memory Pools arbeiten um auch dynamische Sachen zu > entschärfen. Ethernet mit lwIP läuft z.B. so. Also um so Dinge wie Memory Pools. Dazu meinte ich: Rolf M. schrieb: > Klar gibt es Mittel, um trotzdem sicher mit dynamischem Speicher zu > arbeiten. Aber diese müssen im ganzen Programm auch aktiv genutzt > werden. Sprich: Ich mache nicht einfach nur ein klassisches malloc oder new, sondern muss mich dann im gesamten Programm eben mit den Memorypools beschäftigen.
:
Bearbeitet durch User
man muss nicht unbedingt im ganzen Programm mit MemoryPools kämpfen, siehe lwIP. Das kann auch lokal für sich mit einem arbeiten, der Rest der SW kann malloc/new benutzen.
Rolf M. schrieb: > mh schrieb: >> Rolf M. schrieb: >>> Nö, das erledigt der Linker. Ein Speichermanagement zur Laufzeit ist bei >>> statischem Speicher nicht nötig. >> >> Wenn du so argumentierst ... > > Du hast mit der merkwürdigen Argumentation angefangen. Du hast vorher die merkwürdige Behauptung aufgestellt, dass das Problem Speicherfragmentierung größer wird, je kleiner der Speicher. >> bei mir erledigt das Speichermanagement die C++ Standardlib. > > … deren Funktionen du dafür zur Laufzeit aufrufen musst, um den Speicher > für deine Daten zu bekommen. Das ist natürlich ein besonders starkes Argument. Was ist der Nachteil an den Funktionen? Ich kann dir mindestens einen Vorteil nennen. Sie haben einen Rückgabewert. Da kann man rechzeitig drauf reagieren, bevor die heiligen 100k€ Maschine etwas dummes anstellt, wenn sie einen Segmentation Fault habt. > Aber darum ging es eigentlich überhaupt nicht. Es ging um diese Aussage: > > Johannes S. schrieb: >> Und man kann mit Memory Pools arbeiten um auch dynamische Sachen zu >> entschärfen. Ethernet mit lwIP läuft z.B. so. > > Also um so Dinge wie Memory Pools. Dazu meinte ich: > > Rolf M. schrieb: >> Klar gibt es Mittel, um trotzdem sicher mit dynamischem Speicher zu >> arbeiten. Aber diese müssen im ganzen Programm auch aktiv genutzt >> werden. > > Sprich: Ich mache nicht einfach nur ein klassisches malloc oder new, > sondern muss mich dann im gesamten Programm eben mit den Memorypools > beschäftigen. Warum muss man das plötzlich überall machen? Man kann die Pools da einsetzen, wo es sinnvoll ist. Und wo ist das Problem, wenn man sich im ganzen Programm mit Memorypools beschäftigen muss? Auf vielen µC gibt es auch "in Hardware" Memorypools (xram, yram, usb-ram, intern, extern, ...) mit denen du dich beschäftigen musst, wenn du nur statischen Speicher benutzt.
mh schrieb: > Rolf M. schrieb: >> mh schrieb: >>> Rolf M. schrieb: >>>> Nö, das erledigt der Linker. Ein Speichermanagement zur Laufzeit ist bei >>>> statischem Speicher nicht nötig. >>> >>> Wenn du so argumentierst ... >> >> Du hast mit der merkwürdigen Argumentation angefangen. > Du hast vorher die merkwürdige Behauptung aufgestellt, dass das Problem > Speicherfragmentierung größer wird, je kleiner der Speicher. Ja, wird es auch, denn Lücken durch allokierte und wieder freigegebene Bereiche tun bei 4k Speicher halt mehr weh als bei 16 GB. Außerdem kann man bei größerem Speicher komplexere Speichermanager einsetzen, die z.B. separate Bereiche für die am häufigsten vorkommenden Größen haben, um damit die Speicherfragmentierung gering zu halten. Bei sehr kleinem Speicher hat man den Spielraum für sowas nicht. mh schrieb: >>> bei mir erledigt das Speichermanagement die C++ Standardlib. >> >> … deren Funktionen du dafür zur Laufzeit aufrufen musst, um den Speicher >> für deine Daten zu bekommen. > Das ist natürlich ein besonders starkes Argument. Was ist der Nachteil > an den Funktionen? Dass sie fehlschlagen können und das Programm dann irgendwie sinnvoll damit umgehen muss. Wie ich oben schon geschrieben hab, wäre es katastrophal, wenn das ESP beim Bremseingriff aussteigt wegen "out of memory". > Ich kann dir mindestens einen Vorteil nennen. Sie > haben einen Rückgabewert. Da kann man rechzeitig drauf reagieren, bevor > die heiligen 100k€ Maschine etwas dummes anstellt, wenn sie einen > Segmentation Fault habt. Eben nicht. Man kann nicht rechtzeitig vorher reagieren, sondern erst wenn die Allokation fehlschlägt. > Warum muss man das plötzlich überall machen? > Man kann die Pools da einsetzen, wo es sinnvoll ist. > Und wo ist das Problem, wenn man sich im ganzen Programm mit Memorypools > beschäftigen muss? Ich schrieb nur, dass man das halt tun muss und es nicht mit einem einfachen malloc getan ist.
Rolf M. schrieb: > Ja, wird es auch, denn Lücken durch allokierte und wieder freigegebene > Bereiche tun bei 4k Speicher halt mehr weh als bei 16 GB. Außerdem kann > man bei größerem Speicher komplexere Speichermanager einsetzen, die z.B. > separate Bereiche für die am häufigsten vorkommenden Größen haben, um > damit die Speicherfragmentierung gering zu halten. Bei sehr kleinem > Speicher hat man den Spielraum für sowas nicht. Das hängt immer noch von der Anwendung ab, wie anfällig das Speicherallokationsmuster anfällig für Fragmentation ist. Rolf M. schrieb: > Wie ich oben schon geschrieben hab, wäre es > katastrophal, wenn das ESP beim Bremseingriff aussteigt wegen "out of > memory". Kannst du den Qeuelltext eines ESP zeigen, damit ich bewerten kann, ob es überhaupt einen Vorteil von dynamischen Speicher gibt? Sonst ist es ein ziemlich sinnlose Argument für "dynamischer Speicher auf µC ist problemantisch (ohne Einschränkung)". Rolf M. schrieb: > Eben nicht. Man kann nicht rechtzeitig vorher reagieren, sondern erst > wenn die Allokation fehlschlägt. Und wann und wie reagiert man, wenn man nur statischen Speicher nutzt? Oder kannst du den maximalen Speicherverbrauch garantieren? Ich kann das bei meinen Programmen nicht, zumindest nicht ohne den Speicher massiv überdimensionieren zu müssen.
mh schrieb: > Das hängt immer noch von der Anwendung ab, wie anfällig das > Speicherallokationsmuster anfällig für Fragmentation ist. Ja, natürlich tut es das. > Rolf M. schrieb: >> Wie ich oben schon geschrieben hab, wäre es >> katastrophal, wenn das ESP beim Bremseingriff aussteigt wegen "out of >> memory". > Kannst du den Qeuelltext eines ESP zeigen, damit ich bewerten kann, ob > es überhaupt einen Vorteil von dynamischen Speicher gibt? Sonst ist es > ein ziemlich sinnlose Argument für "dynamischer Speicher auf µC ist > problemantisch (ohne Einschränkung)". Na dann ist es ja gut, dass ich sowas nicht behauptet habe. Ich zitiere nochmal die erste Aussage, die ich in diesem Thread geschrieben habe: Rolf M. schrieb: > Es ist nicht grundsätzlich verboten, aber man versucht, es möglichst zu > vermeiden. Je nach Anwendung kann es ggf. verboten sein. Und es gibt > viele Anwendungen, wo dynamischer Speicher auch gar nicht nötig ist. Nun versuchst du, mir zu widersprechen, indem du im Prinzip das gleiche sagst. > Rolf M. schrieb: >> Eben nicht. Man kann nicht rechtzeitig vorher reagieren, sondern erst >> wenn die Allokation fehlschlägt. > Und wann und wie reagiert man, wenn man nur statischen Speicher nutzt? Wenn der alle ist, gibt es einen Linkerfehler, und man weiß, dass man zu wenig Speicher hat, also entweder sparen muss oder einen gößeren Speicher verbauen. Bei dynamischem Speicher ist es oft nicht gerade einfach die Situation zu erkennen und herbeizuführen, in der der Speicherverbrauch maximal ist, um zu ermitteln, ob ich genug Speicher habe. > Oder kannst du den maximalen Speicherverbrauch garantieren? Ja. Wenn das Programm aus dem Linker kommt, weiß ich exakt, wie viel statischen Speicher es braucht. Für dynamischen Speicher gilt das nicht.
:
Bearbeitet durch User
mh schrieb: > Rolf M. schrieb: >> Eben nicht. Man kann nicht rechtzeitig vorher reagieren, sondern erst >> wenn die Allokation fehlschlägt. > Und wann und wie reagiert man, wenn man nur statischen Speicher nutzt? > Oder kannst du den maximalen Speicherverbrauch garantieren? Ich kann das > bei meinen Programmen nicht, zumindest nicht ohne den Speicher massiv > überdimensionieren zu müssen. Rolf spricht von einer klaren Situation mit Anforderungen im embedded Bereich - sehr sehr wenig Speicher, wenig Bewegung, Interrupt-Performanz - also ein kleinst System oder hart Echtzeit-Anforderung du mischt gerade normale Applikationen, Embedded mit genug Ressourcen und ganz kleine Embedded Systeme - einigt euch auf ein Thema sonst ist das total sinnlos hier das eine 4k uC viel stärkere Probleme mit Fragmentierung als eine 16GB System hat - bei gleicher Software - ist hoffe ich allen hier klar
mh schrieb: > Rolf M. schrieb: >> Eben nicht. Man kann nicht rechtzeitig vorher reagieren, sondern erst >> wenn die Allokation fehlschlägt. > Und wann und wie reagiert man, wenn man nur statischen Speicher nutzt? > Oder kannst du den maximalen Speicherverbrauch garantieren? Ich kann das > bei meinen Programmen nicht, zumindest nicht ohne den Speicher massiv > überdimensionieren zu müssen. Nur interessehalber... was machst du dann mit dem Stack? Der ist ja auch dynamisch. Hast du schonmal alle möglichen Verzweigungen überprüft, um den worst-case Stackverbrauch zu ermitteln? Spätestens auf einer Architektur, auf der sich Interrupts unterbrechen können, ist das mindestens ein so großes Problem wie Speicher Fragmentierung. 73
Hans W. schrieb: > Hast du schonmal alle möglichen Verzweigungen überprüft, um den > worst-case Stackverbrauch zu ermitteln? > > Spätestens auf einer Architektur, auf der sich Interrupts unterbrechen > können, ist das mindestens ein so großes Problem wie Speicher > Fragmentierung. Fragmentierung wächst an Stack kann nur eine maximale Tiefe haben - wenn keine Rekursionen vorhanden schon ein Unterschied
cppbert3 schrieb: > Stack kann nur eine maximale Tiefe haben - wenn keine Rekursionen > vorhanden > schon ein Unterschied Das ist richtig, prüft auch ein gutes Tool, doch ist Rekursion oder auch nur der größte Pfad bei funktionsptr. kaum zu messen. Es reicht ja, wann a b aufruft usf. bis z und z dann b aufruft.
A. S. schrieb: > cppbert3 schrieb: >> Stack kann nur eine maximale Tiefe haben - wenn keine Rekursionen >> vorhanden >> schon ein Unterschied > > Das ist richtig, prüft auch ein gutes Tool, doch ist Rekursion oder auch > nur der größte Pfad bei funktionsptr. kaum zu messen. Es reicht ja, wann > a b aufruft usf. bis z und z dann b aufruft. Wenn man solchen Einschränkungen unterliegt sind es auch nicht mehr so viele Varianten in den Aufrufen - sonst könnte man das ja gar nicht prüfen
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.