Entsteht bei C++ ein theoretischer overhead?
-
Mir geht schon seit einiger Zeit ein berühmtes Gerücht nicht aus dem Kopf. Entsteht bei der C++ Programmierung ein overhead? Ob er vernachlässigbar ist, ist egal. Es geht dabei rein um die Theorie.
Man hört auch das insbesondere auf nicht X86 Architekturen ein C Compiler bessere Arbeit macht als ein C++ Compiler. Ist da etwas wares dran?
Ich würde nicht wegen 2 jumps mehr die Programmiersprache wechsel, bin aber sehr Wissensgierig.
Ich kann mir halt nicht vorstellen das ein Objekt, welches ein anderes Objekt hält und ich dessen Methoden aufrufen möchte gleich schnell ist, als ob ich direkt die Funktionen aufrufen würde(ala C).
Hat jemand dazu Links?
-
Ich denke, man kann das nicht so einfach vergleichen. In C++ gibt es Sachen, die es in C nicht gibt, die haben Overhead, z.B. virtuelle Funktionen. Aber du kriegst ja dafür auch was. Du könntest diese Funktionalität selber nachbaun, aber ob du wirklich besser bist als der Compiler, halte ich für fraglich.
Normale Methoden sollten IMHO nicht langsamer gehen als Funktionen, die einen Zeiger auf ein struct übernehmen.
Außerhalb der Objektorientierung fällt mir jetzt auch nichts ein.... was willst du denn vergleichen?
-
Grundsätzlich fällt mir dazu folgendes ein:
- Bei gleichem Code sollte das C++ Ergebnis genauso schnell sein, wie das C Ergebnis.
- C++ Idiome können schneller sein, als äquivalente C Idiome. So ist std::sort meistens schneller als qsort
- C kennt das keyword restrict und C++ noch nicht. Dadurch können vor allem numerische C Programme schneller sein als C++ Programme. Viele C++ Compier haben jedoch eine Erweiterung die auch restrict kennt.
- C++ Konstruktionen, die im Vergleich zu C syntaktischen Zucker darstellen, haben einen Overhead, aber dieser tritt auch in C auf, wenn man dort ähnliches macht.
-
C kennt das keyword register und C++ noch nicht. Dadurch können vor allem numerische C Programme schneller sein als C++ Programme. Viele C++ Compier haben jedoch eine Erweiterung die auch register kennt.
C++ kennt register sehr wohl. Heutige Compiler ignorieren dieses Schlüsselwort aber einfach, da die Optimizer meist besser wissen, wann was in registern zu halten ist.
Vielleicht meinst du restrict?
-
inline verwende ich meistens nur aus Bequemlichkeit und register gar nicht, weil so blöd kann der Compiler nicht sein, dass ich ihm da noch helfen muss.
Was mir wichtiger wäre, aber es scheinbar nicht gibt, ist die Wahrscheinlichkeit eines Sprungs anzugeben. Damit lässt sich bestimmt einiges rausholen, ich freue mich schon auf die Profile-guided optimization im nächsten Visual C++.
-
Also afaik gibts keine Objekte mehr. Die Klassen-Funktionen werden einfach so aufgerufen, die Membervariablen werden über den *this Zeiger angesprochen der imho im ECX steht.
Edit: Das heißt aber nicht, dass es keinen Overhead in C++ gibt.
BTW: Was meinst du mit Overhead? Im Vergleich zu C oder im Vergleich zur "optimalsten" Lösung in Assembler?
MfG SideWinder
-
Ein Beispiel ist vielleicht Doom3. Doom3 ist ja bis auf die Grafik-Engine in C++ geschrieben. Aber warum wurde ausgerechnet die 3d-Engine in C erstellt? Das die/der Programmierer C++ nicht beherrschen denke ich nicht, denn sonst hätten sie das gesamte Spiel in C geschrieben.
Ich habe auch schon öfters gehört das C hardwarenäher ist, was mir ebenfalls nicht einleuchtet, da ich ja mit C++ die komplette C Funktionalität zur Verfügung habe.
-
Helium schrieb:
Vielleicht meinst du restrict?
Ups, genau ich meinte restrict.
-
Das hängt alles von der gewählten Grafik-Library ab:
Wählst du DirectX musst du C++ nehmen.
Wählst du OpenGL kannst du C++ nehmen, da aber keine Wrapper geschrieben werden (Dumm wäre man wenn, kostet bloß Geld) nimmt man lieber gleich C.Auch hier ein Edit: Wenns um C/C++ geht, natürlich kannst du auch Doom3 in VB programmieren - don't think about speed, we just want to get it out of the door
MfG SideWinder
-
Wissensdurstige schrieb:
Ein Beispiel ist vielleicht Doom3. Doom3 ist ja bis auf die Grafik-Engine in C++ geschrieben. Aber warum wurde ausgerechnet die 3d-Engine in C erstellt? Das die/der Programmierer C++ nicht beherrschen denke ich nicht, denn sonst hätten sie das gesamte Spiel in C geschrieben.
Ich habe auch schon öfters gehört das C hardwarenäher ist, was mir ebenfalls nicht einleuchtet, da ich ja mit C++ die komplette C Funktionalität zur Verfügung habe.
Naja das liegt glaub ich eher an dem Typen, der die Grafikengine codet. Muss man halt auch respektieren, warum soll er sich jetzt noch umgewöhnen?
-
Daran liegts sicherlich nicht :D. Good old Johnny ist in der Lage C++ zu programmieren - und alleine schreibt er die Engines sicherlich auch nicht mehr
MfG SideWinder
-
Ich sags dir, ich trau dem ganz ehrlich zu, dass er C++ nicht soooo gut kann. Er ist mit Sicherheit kein schlechter Coder, aber vielleicht hat er sich ja über die Jahre hinweg mit C den Stil versaut??
Naja ok, das sind jetzt nur böse Mutmaßungen, ich frag ihn mal, wenn ich ihn nächstes mal wieder sehe.
-
Wissensdurstige schrieb:
Mir geht schon seit einiger Zeit ein berühmtes Gerücht nicht aus dem Kopf. Entsteht bei der C++ Programmierung ein overhead? Ob er vernachlässigbar ist, ist egal. Es geht dabei rein um die Theorie.
gegenüber assembler ist ein overhead da, weil gar nicht alle assemberbefehle in der sprache verfügbar sind. in asm kann man fein zwei zahlen addieren und dann springen, falls es einen überlauf gab. dieses "falls es einen überlauf gab" ist in c++ nicht direkt ausdrückbar. bei solchen sachen passiert es, daß asm schneller ist.
Man hört auch das insbesondere auf nicht X86 Architekturen ein C Compiler bessere Arbeit macht als ein C++ Compiler. Ist da etwas wares dran?
nichts. gar nichts.
aber altes fortran ist schneller. insbesondere, wenn der prozessor keinen stack hat. denn in fortran ist auch kein stack vorgesehen. in c und c++ aber wohl. das simulieren eines stacks macht auf diesen kisten die sache nicht wirklich schneller.Ich würde nicht wegen 2 jumps mehr die Programmiersprache wechsel, bin aber sehr Wissensgierig.
Ich kann mir halt nicht vorstellen das ein Objekt, welches ein anderes Objekt hält und ich dessen Methoden aufrufen möchte gleich schnell ist, als ob ich direkt die Funktionen aufrufen würde(ala C).
ein objekt, das ein andertes objekt hält.
class Motor{ int leistung; void anzeigeLeistung(){ cout<<leistung<<endl; } }; class Auto{ Motor m; }; ... Auto *a; ... a->m.anzeigeLeistung();
das ist billig.
a->m löst der compiler ja als (Motor)(((char*)a)+offsetM). also nur gecasste, damoit's syntaktisch klappt und einer addidion mit ner konstanten. hier hat die konstante sogar den wert 0 und fliegt raus.
und
a->m.anzeigeLeistung();
ist innendrin nix anderes als
anzeigeLeistung(&a->m);
also ein normaler funktionsaufruf, der als erstes argument nen zeiger auf das objekt kriegt, das links vom punkt stand.
abgesehen von cecaste passierte nur
anzeigeLeistung(a);
das ist ziemlich unmittelbar. in schlimmen fällen passier maximal ein
anzeigeLeistung(a+irgendEinOffset);
egal, wie tief die objekte verschachtelt sind.
also verschachteln und baen von kleinen klassen schadet nicht. verzeicgern schadet genausoviel wie in c. es gibt keinen theoretischen overhead von c++ gegenüber c.in realen programmen sieht es ein wenig anders aus, wie ich jüngst erleben, schmeißt man in c++ so viel wie möglich in boost::shared_ptrs oder wenigstens irgendwelche smart pointers. das kostet. man fasst keinen char* mehr an, sondern macht alles mit strings, das kostet. selbst die ausgabe des winzigsten integers fragt erstmal, wo der user seine tausenderpunkte haben mag, das kostst. man verwendet nur noch vector statt arrays, das kostet. insofern hat c++ in realen programmen nen nachteil. nicht nen rein theoretischen, aber man muss feststelen, daß c++-programme in manchen aspeken langsamer gebaut werden. dem gegenüber stehen die möglichkeiten, die aufgetan werden, weil man ohne roßen aufwand zugriff auf geile algos und datenstrukturen hat. also intro-sort, heaps, avl-trees und vieles mehr. das dürfte für mehr als bloß ausgleich sorgen.
aber warten wir's mal ab. wenn das so weiter geht, haben wir bald nen garbage-collector und haben nen theoretischen overhead.
-
Optimizer schrieb:
...aber vielleicht hat er sich ja über die Jahre hinweg mit C den Stil versaut??
vielleicht? da hilft nur, den cde zu lesen. ich hab mal reingelesen und weiß es nu. es war ganz deutlich.
-
Lass mich auch mal lesen du kleiner Hacker? Oder hab ich dich jetzt missverstanden
MfG SideWinder
-
Überraschen würds mich nicht. Kann ja fast gar nicht anders sein, wenn man sein Leben lang hässliche C-APIs bedient. Ob ich wohl auch berühmt wäre, wenn ich ausgiebig die WinAPI nutzen würde?
-
Optimizer schrieb:
Überraschen würds mich nicht. Kann ja fast gar nicht anders sein, wenn man sein Leben lang hässliche C-APIs bedient. Ob ich wohl auch berühmt wäre, wenn ich ausgiebig die WinAPI nutzen würde?
wenn du wie er TROTZDEM was total geiles machst, klar!
-
ACK @ volkard.
Wenn man C++ Programme so schreiben würde wie C Programme, dann hätten sie keinen Overhead, aber dafür bräuchte man dann nicht C++ sondern könnte gleich C nehmen. Das ist vermutlich der Grund dafür, warum die angesprochene Doom Engine in C geschrieben ist.
Bzgl GC - overhead gegenüber was? GC ist nicht automatisch langsamer - es ist sehr anwendungsabhängig. Siehe http://www.hpl.hp.com/personal/Hans_Boehm/gc/issues.html + den ersten Link dort (Memory Allocation Costs in Large C and C++ Programs)
-
@Ringding: Wie gesagt, dein erster Absatz ist imho Mist.
MfG SideWinder
-
Ringding schrieb:
ACK @ volkard.
Wenn man C++ Programme so schreiben würde wie C Programme, dann hätten sie keinen Overhead, aber dafür bräuchte man dann nicht C++ sondern könnte gleich C nehmen. Das ist vermutlich der Grund dafür, warum die angesprochene Doom Engine in C geschrieben ist.in c++ zahlt man für die abstraktion allein keinen overhead. man kann sehr wohl erheblich weiter von der maschine abheben, ohne auch nur einen takt mehr zu zahlen.
genau deswegen müßte es gerade für engines gebot sein, c++ statt c zu nehmen. allerdings verlangt sauberes c++ vom programmierer manchmal zu viel know how, so daß man es in teams lieber nicht einsetzt.und dann ist anzugucken, was man nrmalerweise schreibt. ich schreibe grerade in c++ nen automaten, der meine html-seiten baut. eingabedaten ca. 100k text. ausgabe daten ca genausoviel text und nochmal so viel html drumherum.
laufzeit ungefähr ne sekunde.
dafür benutze ich der einfachheit halber std::string. von der sekunde laufzeit sind wahrscheinlich 90% warten af die platte. ich erstelle ja recht viele files. den rechnungsanteil könnte ich mit selbergebautem dateileser und selergebauten strings (und am besten noch nem allokator, ne hashtable wäre auch nett, nee ein trie...) wohl mehr als zehnmal so schnell machen. kann auch durchaus hundert mal so schnell werden, das passiert leicht. dann wartet mein prog leider immernoch 0.9s auf die platte und hat nu ne gesamtlaufzeit von 0.901s oder so. also spare ich mir die mühe und nehme mal string, fstream und stringstream aus std.
wenn man in c++ auf speed wert legt, sieht's für c recht schattig aus. es ist zum beispiel kein roblem, einfach mal (nachträglich!) festzustelen, daß nullterminierte stings suboptimal sind und man ieber welche mit start- und endezeiger nehmen mag, weil aufrufe von strlen() so tierisch oft vorkamen. naja, das ist schnell erledigt. in c würde es recht weh tun. man hat mehr felxibilität, die optimalen sachen rauszufinden, indem hier und da an nem schräubchen dreht und wieder mal ein detail optimiert.Bzgl GC - overhead gegenüber was? GC ist nicht automatisch langsamer - es ist sehr anwendungsabhängig. Siehe http://www.hpl.hp.com/personal/Hans_Boehm/gc/issues.html + den ersten Link dort (Memory Allocation Costs in Large C and C++ Programs)
ich kann kein .ps.Z lesen.
werden da auch anwendungen wie mein html-bauer gemessen? wo es niemals auf speed ankam?konstruiere mal ne anwendung, wo ein gc speed bringt.