Ich entwickle eine Anwendung für Embedded Linux (ARM). Es wird 500 Mal pro Sekunde ausgeführt, daher ist Geschwindigkeit wichtig. Ich würde lieber C++ verwenden, aber ich befürchte, dass es langsamer als C sein wird, selbst wenn ich ausgefallene Funktionen wie virtuelle Funktionen meide. Gibt es einen Grund, C zu verwenden, oder ist es genauso gut, in C++ zu schreiben?
C vs. C++ in eingebettetem Linux
Martin Beckett
C++ erleidet im Allgemeinen keine Laufzeiteinbußen gegenüber C – (mit Ausnahme einiger Dinge wie RTTI).
Abgesehen von ein paar ungewöhnlichen Umständen sollte der Compiler in der Lage sein, zur Kompilierungszeit zu bestimmen, welche virtuelle Funktion aufgerufen werden soll, und so keinen Mehraufwand verursachen.
Bearbeiten: Okay, bei einer solchen Vielfalt an Compilern, CPUs, Laufzeitbibliotheken und Betriebssystemen gibt es einige Funktionen von C++, die möglicherweise langsameren Code erzeugen, und es gibt einige Funktionen, die möglicherweise schnelleren Code erzeugen.
Aber können wir uns alle darauf einigen, dass C++ nicht automatisch ausgeschlossen ist? eingebettet mehr verwenden?
-
Wenn Sie C++ als „hässliches C“ verwenden (überall zusätzliche Umwandlungen), dann ist das, was Sie gesagt haben, wahr. Aber sobald Sie anfangen, etwas zu verwenden, das C++ „komfortabel“ macht, entsteht viel mehr Overhead, der nicht optimiert werden kann.
– R.. GitHub HÖRT AUF, ICE ZU HELFEN
28. Februar 2011 um 21:34
-
Virtuelle Funktionen und Vorlagen sollten keine Kosten verursachen. Eine Ausnahme bilden Nullkosten, wenn kein anständiger Compiler aufgerufen wird. Dynamic_cast funktioniert normalerweise ohne RTTI – mit einigen Warnungen. Die Codegröße könnte ein Problem sein – aber es hängt natürlich davon ab, was Sie unter „eingebettet“ verstehen
– Martin Beckett
28. Februar 2011 um 22:00 Uhr
-
Ausnahmen haben negative Kosten, wenn Sie die C-Fehlerbehandlung aus dem normalen Codefluss entfernen können. Optimierer können problemlos für den Nicht-Ausnahmefall optimieren, wissen aber nicht, ob eine C-Funktion im Fehlerfall 0,1 oder -1 zurückgibt.
– MSalters
1. März 2011 um 8:43
-
Ich verwende C++11 und Metaprogrammierung auf einem eingebetteten ARM mit 32 KB Flash! Ich habe festgestellt, dass Sie mit einem modernen Compiler (ich verwende GCC 4.6) C-Code nach C++ portieren können und dabei manchmal eine Größenverringerung feststellen. constexpr ist ein wichtiges Werkzeug.
– odinthenerd
28. Juni 2013 um 18:18
-
STL-Container (implementiert mit Vorlagen) sind tatsächlich ein großer Gewinn, wenn Ihr Code wichtige Datenstrukturen enthält. Die Implementierungen sind so gut wie möglich – und wahrscheinlich besser als diejenigen, die Sie selbst schreiben würden. Bei Bedarf können Sie auch eine Poolzuweisung vornehmen.
– Marko
28. Juni 2013 um 18:18
j4x
In C++ gibt es Dinge wie Template-Metaprogrammierung, die in der Kompilierungszeit mehrere Situationen lösen, in denen C oder eine andere prozedurale Programmiersprache zur Laufzeit zu tun hätte.
Ich sollte mehr sagen. Die Metaprogrammierung von Vorlagen und einige Tricks zur Klassenvererbung sind wirklich erstaunlich. Es kann Ihnen viel Verarbeitungszeit ersparen, die Sie sonst mit „Ifing“ und „Switching“ verbringen würden.
Das bedeutet, dass C++ bei guter Ausführung tatsächlich schneller als C sein kann.
Offensichtlich können Sie mit C++ „in C“ programmieren, ohne dass dafür irgendwelche Nachteile entstehen. Wenn Sie C++ nicht besonders mögen, würde ich Ihnen raten, „C auf C++“ oder „C mit C++-Erweiterungen“ zu machen, nur um von den C++-Verbesserungen zu profitieren, aber der eigentliche Vorteil, den Sie haben, liegt in der Programmierung von C++ Weg. Dort sehen Sie, dass C++ Istteilweise schneller oder sauberer als C oder zumindest so schnell wie.
Hab keine Angst. Stellen Sie sich C++. Nach stdc++ (gegen libc) wird es fast keinen Overhead bei der Codegröße geben. Wenn Ihre Anwendung mittelgroß bis groß ist, wird sie verdünnt.
Ich verwende C++ vom einfachen 8-Bit-ATmega bis hin zu Marvells ARM9, über AVR32 UC3 und Cortex-M3 und finde es immer profitabel.
Wenn Sie in einer bestimmten Situation konkreten Rat benötigen, fragen Sie einfach nach.
-
Das ist die Antwort, auf die ich gehofft habe. Es macht viel mehr Spaß, C++ zu schreiben, selbst für einfache Dinge wie die Möglichkeit, eine Variable zu deklarieren, wenn Sie sie benötigen (im Gegensatz zum Blockanfang in C). Und natürlich bevorzuge ich die Klassenkapselung gegenüber globalen C-Funktionen. Ich hoffe, eine dynamische Speicherzuweisung oder irgendetwas Exotisches zu vermeiden.
– Gregory Chrapunovich
3. März 2011 um 22:28
-
Die Vorteile von C++ in der Embedded-Welt sind weitreichend. Ich habe festgestellt, dass __attribute((always_inline)) ein Geschenk des Himmels ist, wenn abstrakte Schnittstellen ins Nichts kompiliert werden und nur eine stärkere statische Überprüfung wichtiger Dinge übrig bleibt.
– odinthenerd
28. Juni 2013 um 18:12
Der Hauptgrund für die Wahl von C gegenüber C++ ist die Größe der kompilierten Binärdatei, die für eingebettete Systeme eine echte Einschränkung darstellen kann.
Bei der Leistung gibt es keinen messbaren Unterschied, wenn Sie die Sprache richtig verwenden. Sie können langsamen C-Code genauso einfach schreiben wie langsamen C++, solange Sie sich der Mechanismen unter der Haube dessen bewusst sind, was Sie schreiben, sollten Sie mit beidem zurechtkommen.
-
Der Größenunterschied ist vernachlässigbar, sofern es sich um die C-Version handelt funktional gleichwertig zur C++-Version. Wenn beispielsweise die C++-Version Vererbung verwendet, muss die C-Version auch das Äquivalent codieren, keine Abkürzungen. Meiner Erfahrung nach ist die Größe kein Problem.
– Thomas Matthews
28. Februar 2011 um 20:02
-
@Thomas: Das stimmt einfach nicht, denn ein großer Teil des Bibliothekscodes, der eingelesen wird, verfügt über eine große Obermenge der erforderlichen Funktionalität und der Linker kann nicht bestimmen, welche Teile weggelassen werden können. Verknüpfen Sie ein C-Hello-World-Programm statisch mit einer beliebigen vernünftigen C-Bibliothek (jedes der BSDs, uClibc, Bionic usw. – nur nicht mit Glibc, dessen stdio im Wesentlichen in C++ geschrieben ist) und vergleichen Sie ein entsprechendes statisch verknüpftes C++-Programm mit iostream.
– R.. GitHub HÖRT AUF, ICE ZU HELFEN
28. Februar 2011 um 21:37 Uhr
-
@R..: Wenn Sie eine geeignete Implementierung von libc auswählen, sollten Sie fair sein und einen ebenso geeigneten iostream auswählen. Dietmar Kuehl hat (vor etwa 10 Jahren) bewiesen, dass Hello, World in C++ kleiner sein kann. Einfacher Grund: der Linker dürfen beseitigen
operator<<ostream&, float)
aber nichtcase 'f':
von demprintf()
Implementierung.– MSalters
1. März 2011 um 8:46
-
Die Bibliotheksgröße kann (theoretisch) in manchen Umgebungen ein Problem sein, aber in der ursprünglichen Frage wird eingebettetes Linux erwähnt, es handelt sich also mindestens um ein 32-Bit-System und das Betriebssystem selbst ist groß genug. Daher bezweifle ich, dass die Größe in diesem Fall eine Rolle spielt 🙂
– Benutzer396672
1. März 2011 um 9:48
-
Ich baue derzeit ein eingebettetes Linux-basiertes System auf, bei dem ich mich dafür entschieden habe, dem Gerät mehr Flash hinzuzufügen, um die dynamischen C++-Bibliotheken einbinden zu können. Zumindest für mich war also die Größe ein echter Faktor.
– Erik
1. März 2011 um 9:51
Solange Sie die von Ihnen verwendeten Funktionen einschränken, wird die Leistung in C++ gegenüber C kaum oder gar nicht beeinträchtigt. Zu den Funktionen, die Sie vermeiden sollten, gehören: Ausnahmen, RTTI und eine möglichst flache Klassenhierarchie (und virtuelle Funktionen sparsam verwenden).
C++ ist in Ordnung, solange Sie über genügend RAM und Flash in Ihrem eingebetteten System verfügen. Die C++-Laufzeitbibliothek (libstdc++) ist umfangreich und kommt zusätzlich zur C-Standardbibliothek (libc) hinzu, auch wenn Sie nur C++ verwenden.
-
In einem eingebetteten System bindet man nur die Bibliotheken ein, die benötigt werden. Für eine Desktop-Version verwendete Bibliotheken sind normalerweise viel größer und weisen keinen Größenzusammenhang auf. Blödsinn über Größenprobleme. Siehe meinen anderen Beitrag zu SO.
– Thomas Matthews
28. Februar 2011 um 20:03
-
Es ist ein mutiger Schritt, dagegen zu argumentieren, dass libstdc++ RAM und Flash erfordert …
– GT.
28. Februar 2011 um 20:43
-
@Thomas: Ich würde gerne sehen, wie du einen Weg findest, es zu machen
libstdc++
klein.uClibc++
existiert aus einem Grund; Leider ist es ziemlich unvollständig.– R.. GitHub HÖRT AUF, ICE ZU HELFEN
28. Februar 2011 um 21:38
Gemeinschaft
Sie können C++ verwenden, seien Sie jedoch besonders vorsichtig.
Behalten Sie die Größe Ihrer Linker-Map-Datei im Auge. Sie können es finden, einschließlich einer Menge Dinge, die Sie nicht brauchen, nur anhand einer unschuldig aussehenden Erklärung.
Für Geschwindigkeit, Profil oder Zufalls-Pause oft. Es ist super einfach, mehr zu tun new
s und delete
s, als Sie wirklich benötigen, insbesondere bei Containerklassen, und seien Sie bei Dingen wie Iteratoren sehr vorsichtig. Oftmals tun sie einem ungebeten einen Gefallen.
Sie können den Code auf Assemblerebene schrittweise durchgehen, um sicherzustellen, dass er nur das tut, was Sie tatsächlich benötigen. Dies sollte in etwa dem C-Code entsprechen.
-
In einem eingebetteten System bindet man nur die Bibliotheken ein, die benötigt werden. Für eine Desktop-Version verwendete Bibliotheken sind normalerweise viel größer und weisen keinen Größenzusammenhang auf. Blödsinn über Größenprobleme. Siehe meinen anderen Beitrag zu SO.
– Thomas Matthews
28. Februar 2011 um 20:03
-
Es ist ein mutiger Schritt, dagegen zu argumentieren, dass libstdc++ RAM und Flash erfordert …
– GT.
28. Februar 2011 um 20:43
-
@Thomas: Ich würde gerne sehen, wie du einen Weg findest, es zu machen
libstdc++
klein.uClibc++
existiert aus einem Grund; Leider ist es ziemlich unvollständig.– R.. GitHub HÖRT AUF, ICE ZU HELFEN
28. Februar 2011 um 21:38
Chris Stratton
Der eigentliche Schlüssel zu größen- und geschwindigkeitseffizientem Code, ob eingebettet oder nicht, liegt darin, dass der Programmierer die Auswirkungen seiner Entscheidungen vollständig versteht.
In gewisser Weise bietet C++ mehr Möglichkeiten, bei denen etwas Teures täuschend unschuldig aussehen kann. Äquivalente Funktionen zu C++-Funktionen erfordern oft mehr Tinte auf der Seite, was dazu führen kann, dass man sich etwas mehr Gedanken über die möglichen Kosten macht. Aber es ist keineswegs ein absolutes Muss – C (und seine Bibliotheken) bergen auch das Risiko täuschend harmloser Kosten.
Letztendlich gibt es keinen Ersatz dafür, zu verstehen, wonach Sie in jeder Codezeile gefragt haben.
Virtuelle Funktionen gehören nicht zu den Dingen, die Sie vermeiden sollten. Die manuelle Implementierung derselben Funktionalität in C ist nicht schneller als die vom Compiler generierte Version, und der C++-Compiler ist gut darin, sie wegzuoptimieren, wenn sie nicht benötigt wird.
– Martin York
28. Februar 2011 um 20:00 Uhr
@Martin hat recht. Der Aufruf virtueller Funktionen kostet nur ein oder zwei Anweisungen, und wenn Sie das wirklich brauchen, müssten Sie es ohnehin in C tun.
– Mike Dunlavey
28. Februar 2011 um 20:44
Einige interessante verwandte Lektüre finden Sie hier: stackoverflow.com/questions/2039444/…
– Emile Cormier
28. Februar 2011 um 20:54
Probieren Sie sowohl C als auch C++ aus und messen Sie dann die resultierenden Binärdateien auf dem eingebetteten Gerät. Wenn Sie nicht zwei Versionen der Anwendung schreiben möchten, verwenden Sie einfach die Sprache, mit der Sie besser vertraut sind (C++).
– pmg
28. Februar 2011 um 21:19 Uhr