STL in eingebetteter Umgebung

8

Ich bin ein C ++ - Programmierer und habe im Laufe der Jahre die Vorstellung erfahren, dass STL nicht gut für den Einsatz in eingebetteten Umgebungen ist und daher normalerweise nicht verwendet werden kann Embedded-Environment-basierte Projekte. Ich glaube, STL-Bibliotheken wie Boost sind viel leistungsfähiger und bieten eine viel schnellere & amp; weniger fehleranfällige Mittel der Entwicklung (natürlich ist die Syntax wenig einschüchternd, aber sobald ich denke, dass es ein echter Schatz ist). Auch finde ich die Behauptungen, dass STL schwer ist und den endgültigen Fußabdruck des Codes absurd erhöht, weil es nur templatesiert wird werde kompilierbaren Code bekommen, den er verlangte, und nicht die gesamte STL.

Meine Frage ist, was sind die Gründe dafür, dass dieser Populist (zumindest die meisten Leute um mich herum denken) die Vorstellung, die STL anruft, nicht für eingebettete Umgebung ist?

Ich sehe eine Frage von ähnlicher Natur, aber hier erwarte ich Hilfe, indem ich hier die Vor- und Nachteile von STL und eingebetteter Umgebung aufzeige.

Bearbeiten: also hier werde ich die Punkte addieren, wie die Antworten kommen:
1. Portabilitätsprobleme 2. Bewältigung von großen Dynamicle-Zuweisungen durch STL-Container 3. STL ist schwer zu debuggen 4. Tiefe Funktionsaufrufe in STL führen zu geringer Leistung für Compiler, die mit Inlining schwach sind (Power of functors nutzlos!)

    
Alok Save 04.10.2010, 07:35
quelle

11 Antworten

9

STL hat ziemlich viele Probleme damit (wie hier von dokumentiert) EASTL ), auf einem eingebetteten System oder kleinen System ist das Hauptproblem in der Regel die Art und Weise, wie es seinen Speicher verwaltet. Ein gutes Beispiel dafür war der PSP-Port von Aquaria .

Mein Rat ist jedoch erster Test, bevor Sie den Annahmen folgen , wenn der Test zeigt, dass Sie einfach zu viel Platz / Prozessor-Zyklen verwenden, dann könnte eine oder zwei Optimierungen es in den Bereich von ' verwendbar '.

Schließlich ist der Boost Template-basiert. Wenn Sie also die Größe des generierten Template-Codes betrachten, wird es genauso wie bei STL funktionieren.

Bearbeiten / Aktualisieren:

Um meine letzte Aussage zu klären (die sich nur auf Boost VS STL bezog). In C können Sie (ab) den gleichen Code verwenden, um den gleichen Job für verschiedene Strukturen mit demselben Header (oder Layout) auszuführen, aber mit Templates erhält jeder Typ seine eigene Kopie (ich habe nie getestet, ob Compiler vorhanden sind) Schlau genug, um dies zu tun, wenn "für die Größe optimieren" erstellt wird, obwohl es genau so ist (auf einer Maschinen- / Baugruppenebene) wie eine, die gerade erzeugt wurde. Boost hat den Vorteil, viel sauberer zu lesen und viel mehr Dinge zu haben, aber das kann zu langen Kompilierzeiten aufgrund einer großen Anzahl von (manchmal sehr großen) Headern führen. STL gewinnt, weil Sie Ihr Projekt weitergeben können und keinen Download / Begleitung von Boost benötigen.

    
Necrolis 04.10.2010, 07:45
quelle
8

Das hängt davon ab, was Sie unter eingebettet verstehen. Auf Atmel8-Systemen gibt es sehr wenig RAM. So wenig, dass du keinen vernünftigen Malloc haben kannst. Sie möchten in diesem Fall den Speicher sehr explizit verwalten, wahrscheinlich mit statischen Arrays des von Ihnen benötigten Typs. Wenn Sie das haben, brauchen Sie die meisten STL im Grunde genommen nicht.

Auf Armsystemen hast du jede Menge Widder. Verwenden Sie STL!

    
quelle
3

Ich bin auf diese Präsentation gestoßen: Standard-C ++ für die Programmierung eingebetteter Systeme

Der Großteil der Komplexität mit Templates liegt beim Compiler als beim Laufzeitsystem und das ist teilweise das Problem - da wir nicht genau wissen, wie viel eine Optimierung der Compiler erreichen kann. In der Tat soll C ++ - Code, der auf STL basiert, kompakter und schneller sein als C ++ - Code, der keine Vorlagen und sogar C-Code verwendet!

    
kartheek 04.10.2010 08:03
quelle
3

Es gibt eine gewisse Logik hinter der Vorstellung, dass Vorlagen zu größerem Code führen. Die Grundidee ist ziemlich einfach: Jede Instanziierung einer Vorlage erzeugt im Wesentlichen separaten Code. Dies war besonders bei frühen Compilern problematisch - da Vorlagen (typischerweise) in Kopfzeilen eingefügt werden müssen, sind alle Funktionen in einer Vorlage inline . Das heißt, wenn Sie zum Beispiel vector<int> in 10 verschiedenen Dateien instanziiert haben, haben Sie (theoretisch) 10 separate Kopien jeder Mitgliedsfunktion, die Sie verwenden, eine für jede Datei, in der Sie sie verwenden.

Jeder einigermaßen aktuelle Compiler (weniger als, sagen wir, 10 Jahre alt) wird eine gewisse Logik im Linker haben, um diese wieder zusammenzufügen, so dass vector<int> in 10 Dateien nur eine Kopie jeder von Ihnen verwendeten Member-Funktion erzeugt in die endgültige ausführbare Datei gehen. Zum Besseren oder Schlechteren jedoch, sobald es "bekannt" wurde, dass Templates aufgeblähten Code produzieren, haben viele Leute nicht wieder nachgesehen, ob es wahr geblieben ist.

Ein anderer Punkt (der weiterhin zutrifft) ist, dass Vorlagen die Erstellung eines ziemlich komplexen Codes erleichtern. Wenn Sie in C selbstständig schreiben, sind Sie im Allgemeinen stark motiviert, den einfachsten Algorithmus, die Sammlung usw. zu verwenden, die die Aufgabe erfüllen - ausreichend motiviert, dass Sie wahrscheinlich Details wie die maximale Anzahl überprüfen von Gegenständen, die Sie treffen könnten, um zu sehen, ob Sie mit etwas wirklich Einfachem durchkommen können. Eine Vorlage kann die Verwendung einer Sammlung für allgemeine Zwecke so einfach machen, dass Sie solche Dinge nicht überprüfen müssen. Sie haben also zum Beispiel den gesamten Code, um einen ausgeglichenen Baum zu erstellen und zu pflegen, auch wenn Sie es nur sind B. maximal 10 Elemente speichern, so dass ein einfaches Array mit linearen Suchvorgängen Speicher spart und normalerweise auch schneller läuft.

    
Jerry Coffin 04.10.2010 08:44
quelle
2

Ich denke, die Wahl hängt von Ihrer (n) Zielplattform (en) ab. Wenn Sie einen korrekten C ++ - Compiler haben und den dynamisch zugewiesenen Speicher nicht stören, wenn Sie Container verwenden, sehe ich kein Problem.

    
Nikko 04.10.2010 07:41
quelle
2

Wie schon gesagt wurde, gibt es eine breite Palette von "eingebetteten" Systemen. Ich gebe meine Perspektive, die sich auf sicherheitskritische und harte Echtzeitsysteme konzentriert.

Die meisten Richtlinien für sicherheitskritische Systeme verbieten einfach die Verwendung von dynamischen Speicherzuweisungen. Es ist einfach einfacher und sicherer das Programm zu entwickeln, wenn Sie sich nie Sorgen machen müssen, dass ein malloc / neuer Anruf fehlschlägt. Und bei lang laufenden Systemen, bei denen eine Heap-Fragmentierung auftreten kann, kann man nicht leicht beweisen, dass die Speicherzuweisung nicht fehlschlägt, selbst auf einem Chip / System mit großen Speichermengen (besonders wenn das Gerät jahrelang ohne Neustart laufen muss).

In Szenarios, in denen es enge Zeitvorgaben gibt, sind die mit der dynamischen Speicherzuordnung und Instanziierung komplexer Objekte verbundenen Unsicherheiten häufig zu groß, um damit umzugehen. Dies ist der Grund, warum viele Programmierer, die in diesen Bereichen arbeiten, bei C bleiben. Sie können C-Quelle betrachten und erraten, wie lange eine Operation dauert. Mit C ++ ist es für einfach aussehenden Code einfacher, länger zu dauern als es scheint. Diejenigen, die C ++ in solchen Systemen verwenden, neigen dazu, sich an einfachen einfachen Code zu halten. Und Code, der normalerweise schnell ist, aber gelegentlich eine lange Ausführungszeit benötigt, ist schlechter als Code, der langsamer aber konsistent ist.

Was ich bei größeren Projekten gemacht habe, ist die Isolierung der Echtzeit- und kritischen Funktionen vom Rest. Das nicht-kritische Zeug kann mit Standardwerkzeugen wie dem STL geschrieben werden. Das ist in Ordnung, solange das Betriebssystem den kritischen Teilen nicht im Weg steht. Und wenn ich nicht garantieren kann, dass es solche Interaktionen nicht gibt, dann benutze die Tools überhaupt nicht.

    
sbass 04.10.2010 12:30
quelle
2

Ich war in einem eingebetteten Projekt, das C ++ und STL in einem sehr eingeschränkten System verwendete (Speicher in einem Bruchteil eines Megabytes, ARMv4 bei niedriger Geschwindigkeit). In den meisten Fällen war STL super, aber es gab Teile, die wir überspringen mussten (zum Beispiel std :: map benötigte 2-4k Code pro Instantiierung [was eine große Zahl im Verhältnis zu unserer ROM-Größe ist], und wir hatten) unser eigener Ersatz für std :: bitset [es war vielleicht ~ 1k ROM]). Aber, std :: vector und std :: list waren sehr hilfreich, wie boost :: intrusive_ptr für die Referenzzählung (shared_ptr war viel zu groß, etwa 40 Bytes RAM pro Objekt!).

Der einzige Nachteil bei der Verwendung von STL ist, dass Sie keine Fehlerbehebungsfunktion haben, wenn Ausnahmen deaktiviert sind (was sie für uns waren, da Ausnahmen und RTTI in unserem Compiler nicht billig waren). Zum Beispiel, wenn eine Speicherzuweisung irgendwo im Code in dieser Zeile (std :: map-Objekt) fehlgeschlagen ist:

%Vor%

Sie würden es nicht sehen und der Code würde einfach still weiter voranschreiten; Wahrscheinlichkeiten sind das Objekt ist jetzt in einem gebrochenen Zustand, aber Sie würden nicht bis viel später stürzen.

Davon abgesehen hatten wir großen Erfolg mit C ++ und STL. Wie ein anderes Poster sagte, probieren Sie es auf Ihrem System aus und messen Sie, welche Teile von STL funktionieren. Als Nebenbemerkung gibt es einen tollen technischen Bericht über die C ++ - Leistung, die allgemein gut ist: Ссылка

    
Jared Grubb 04.10.2010 15:49
quelle
1

Viele denken, dass C ++ (aus vielen Gründen, wie Portabilität) nicht gut in eine eingebettete Umgebung passt. Es gibt viele Arten von eingebetteten Umgebungen und STL ist sicherlich in Ordnung für einige von ihnen.

Im Allgemeinen ist "leistungsfähiger" immer eine Phrase, die Sie fürchten müssen, wenn Sie etwas für eine ressourcenbeschränkte Umgebung wählen müssen, da Sie oft etwas weniger leistungsfähiges und kontrollierbareres wollen. Vor allem, wenn "leistungsfähiger" bedeutet, dass der Entwickler (oder derjenige, der den Code später verwaltet) weniger Verständnis für die zugrunde liegende Implementierung hat.

    
Ofir 04.10.2010 07:37
quelle
1

Es hängt von der Art des eingebetteten Systems ab.

Ein solches System kann einige Kilobyte RAM (oder weniger) haben, oder es kann viele Megabytes oder sogar Gigabytes haben. Speicherbeschränkungen können also ein Problem darstellen oder nicht.

Wenn das System Echtzeitbeschränkungen hat, sind einige Teile oder Verwendungen von STL möglicherweise für einige Teile Ihrer Anwendung nicht geeignet. Container-Klassen basieren in hohem Maße auf dynamischer Speicherzuweisung, Neuzuordnung und Kopieren von Objekten. Dies ist meistens sehr unbestimmt. Wenn Sie also zeitkritischen Code verwenden, haben Sie keine Möglichkeit, die Einhaltung von Fristen zu garantieren.

Das soll nicht heißen, dass STL selbst in Echtzeitanwendungen nicht verwendet werden kann. Aber Sie müssen den Code sorgfältig entwerfen, damit Sie wissen, dass einige nicht-deterministische Operationen während eines zeitkritischen Prozesses nicht auftreten.

    
Clifford 04.10.2010 19:06
quelle
0

Für mich ist das nur ein guter Grund, eine Bibliothek nicht zu verwenden, wenn sie nicht in begrenzte Beschränkungen passt oder ihre Größe später problematisch sein kann. Wenn das kein Problem für Sie ist, gehen Sie dafür. Auf jeden Fall kannst du nicht besser werden.

    
Luka Rahne 04.10.2010 08:16
quelle
0

Ich habe keine Nachteile bei der Verwendung der STL in eingebetteten Systemen erfahren, und ich beabsichtige, sie in meinem aktuellen Projekt zu verwenden. Boost auch.

    
ExpatEgghead 04.10.2010 08:23
quelle

Tags und Links