Entsteht bei C++ ein theoretischer overhead?
-
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.
-
Wenn C-Programme das benötigen, was C++ bietet, dann haben sie dabei auch mindestens den gleichen Overhead... und sind doppelt so lang. Schonmal jemand virtuelle Methoden mit Funktionszeigern implementiert? *kotz*
-
Jester schrieb:
Wenn C-Programme das benötigen, was C++ bietet, dann haben sie dabei auch mindestens den gleichen Overhead... und sind doppelt so lang. Schonmal jemand virtuelle Methoden mit Funktionszeigern implementiert? *kotz*
theoretisch kann man die auch mit switch implementieren. vielleicht mir arg vielen makros?
ja, der code wird ein wenig groß. aber der code kann schneller werden, als der funktionszeigercode, weil der ganze apparat inline bleiben kann und der optimizer vollen zugriff drauf hat. funktionszeiger und virtuelle funktionen machen den optimierer leider blind an der sprungstelle.
wenn man sehr viel zeit hat und genau weiß, was man tut, kann man in der tat in c schneller sein, wenn man es mit c++ vergleicht und einem, der es nicht drauf angelegt hat, mindestens so schnell wie der mit c zu sein.
-
Ich könnte mir vorstellen, dass es (natürlich jetzt konstruiert) mit GC sehr performant wäre, in einer Schleife ständig temporäre Objekte (gerne auch unterschiedlicher Größe) zu erstellen, am Ende aber nur noch ne kleine Anzahl der Objekte zu referenzieren, bevor die Reinigung durchgeführt wird.
Das Aufsammeln von Garbage kostet nämlich nichts (wenn es keine finalizer gibt()) und es werden bei jeder Reinigung nur die referenzierten Objekte verschoben, womit der ganze Heap wieder frei wird.Ich glaub, da könnte so ne verkettete Liste schon richtig abloosen, wenn die Objekte auch noch verschieden Groß sind, das Allokieren auf nem fragmentierten Heap ist nicht das schnellste.
Jetzt zweifle ich natürlich auch nicht daran, dass du speziell für diesen Fall wieder nen schnelleren Allokator schreiben kannst.
Wer's mag. :p
-
volkard schrieb:
ich kann kein .ps.Z lesen.
werden da auch anwendungen wie mein html-bauer gemessen? wo es niemals auf speed ankam?Kind, du hörst dich nach einem erfahrenen Entwickler an, und dann das?
http://www.visotech.at/~sr/CU-CS-665-93.pdf
(leider ist das .ps mit Pixel-Font gemacht, daher schaut das so grauslich aus)Was du schreibst, stimmt schon, aber man muss halt auch einen entsprechenden Aufwand reinstecken, wenn man die Sachen wirklich schnell kriegen will. In C kommt man gar nicht erst in Versuchung, so oft malloc/free zu verwenden, weil's mühsam ist. In C++ geht alles so leicht, dass man nicht groß darüber nachdenkt.
-
Optimizer, verschieben kann man leider nichts in C/C++, weil dann die Pointer darauf ungültig würden.
-
Das ist mir schon bekannt, aber nicht mein Problem. Hat ja keiner gesagt, dass ich nen C++ GC verwenden muss. :p
Das verträgt sich sowieso überhaupt nicht mit den Pointern. Gibt ja nicht umsonst bei MS managed C++ die Referenztypen für den managed Heap.Foo^ myFoo = new Foo();
wer's mag...
-
btw, da gibt es natürlich schon Tricks. Man muss halt dann Pointer auf Pointer nehmen, dann muss man beim Verschieben nur den Pointer anpassen, der direkt auf das Objekt zeigt. Aber solange man an der Adresse rumh4x0rn kann, ist es IMHO nicht sicher, einen GC zu verwenden.
-
Ringding schrieb:
volkard schrieb:
ich kann kein .ps.Z lesen.
Kind, du hörst dich nach einem erfahrenen Entwickler an, und dann das?
http://www.visotech.at/~sr/CU-CS-665-93.pdfthx.
unten hab ich die datei schon mal. kann leider kein .pdf lesen...
naja, ich schätze, den acrobat reader zu installieren, wäre jetzt mal an der zeit.
-
Ringding schrieb:
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)
ob mit oder ohne gc. die performance des verwendete allokators ist stark abhängig von der anwendung.
vorhin wurde gesagt, daß man in c viel seltener malluc/free benutzt, weils da nicht so einfach ist. richtig! das hat zur wirkung, daß man in c lieber wenige große speicherblöcke anlegt, während man in c++ gerne für jedes popelobjekt speicher anlegt (sagt so ähnlich auch alexandrescu bei seinem small object allocator in modern c++ design). das hat natürlich krasse wirkung auf den zu verwendenden allokator. für c++ sollte man auf jeden fall nen small object allocator davorspannen.
und natürlich gibts inzwishcen auch einige leute, die zwar die sprache c benutzen aber volle pulle c++-stil. und umgegehrt gibts die leute auch, die gerademal printf/malloc durch cout/new ausgetuascht haben und fleißig c in ihren c++-compiler stecken.
mit nem angemessenen small object allocator kann man schon ne ganze menge raushauen, würde ich sagen. und den kann man ja erstmal sogar abschreiben. dann kommen natürlich uch die allokatoren zum zuge, die man dazukaufen kann. sind aber immer irgendwie stangenware. sie können nicht ganz genau an die anwendung, die man hat, angepaßt werden.
die ganzen stl-container erlauben, daß man nen eigenen allokator denen mitgibt. das ist was feines. da kann man mit fast nullaufwand auch die speicherfreigaben delayen, bis der ganze container stirbt, wenn man das mag. kann ja sein, daß man mal nen relativ kurzebigen container hat. man kann von vorn herein was für die speicherlokalität tun, was kein zugekaufter universalallokator tun könnte. wegen solcher sachen kriegt man vorläufig immer einen tick mehr speed, wenn man den allokator im source zur verfügung hat.
-
Optimizer schrieb:
Das ist mir schon bekannt, aber nicht mein Problem. Hat ja keiner gesagt, dass ich nen C++ GC verwenden muss. :p
Das verträgt sich sowieso überhaupt nicht mit den Pointern. Gibt ja nicht umsonst bei MS managed C++ die Referenztypen für den managed Heap.Foo^ myFoo = new Foo();
wer's mag...
Das ist ziemlich cool. Aber es heißt gcnew nicht new. new leagt auf dem normalen Freestore an, gcnew auf dem Heap der CLR.
Allgemein finde ich C++/CLI ziemlich cool.
-
SideWinder schrieb:
Lass mich auch mal lesen du kleiner Hacker? Oder hab ich dich jetzt missverstanden
Dazu musst du kein großer Cracker sein, da idSoftware die Quellcodes ihrer Spiele nach einiger Zeit unter der GPL veröffentlicht
http://www.idsoftware.com/downloads/
-
Also ich kann da nichts runterladen...
-
-
der_held schrieb:
Das ist ziemlich cool. Aber es heißt gcnew nicht new. new leagt auf dem normalen Freestore an, gcnew auf dem Heap der CLR.
ups stimmt, ich wollte auch schreiben:
Foo^ myFoo = __gc new Foo();
Aber stimmt, neuerdings heißt es sogar gcnew.
-
Eine kurze Zusammenfassung(korrigiert mich bitte, falls ich falsch liege):
Wenn ich in C++ auch char Arrays anstatt Strings und normale Arrays anstatt Container verwende, dann erreiche ich die selbe Performance wie bei C(virtuelle Methoden vergessen wir erstmal).
-
Hm ja. Das heißt zwar nicht, dass es unbedingt schneller ist, aber immerhin ist es das selbe (bis auf die Möglichkeit, in C99 restrict zu verwenden).
-
Eine kurze Zusammenfassung(korrigiert mich bitte, falls ich falsch liege):
Wenn ich in C++ auch char Arrays anstatt Strings und normale Arrays anstatt Container verwende, dann erreiche ich die selbe Performance wie bei C(virtuelle Methoden vergessen wir erstmal).
Nein, es geht darum, dass ein C Compiler und ein C++ Compiler den gleichen Code gleich umsetzen wird. In C++ benutzt man aber ein anderes Design für seine Anwendungen und wenn man pech hat, kann das Design eben langsammer sein, als das C Design was man wählt.
Mit der STL hat das nichts zu tun.