Leistung von verwaltetem C ++ - Vs UnManaged / natives C ++

8

Ich schreibe eine sehr leistungsfähige Anwendung, die Hunderte von Ereignissen in Millisekunden verarbeitet und verarbeitet.

Ist nicht verwaltetes C ++ schneller als verwaltetes c ++? und warum?

Managed C ++ behandelt CLR statt OS und CLR kümmert sich um die Speicherverwaltung, was den Code vereinfacht und wahrscheinlich auch effizienter ist als Code, der von "einem Programmierer" in nicht verwaltetem C ++ geschrieben wurde? oder gibt es einen anderen Grund? Wie kann man dann bei der Verwendung von managed die dynamische Speicherzuweisung vermeiden, die einen Performance-Hit verursacht, wenn alles für den Programmierer transparent ist und von CLR gehandhabt wird?

Wenn ich auf meine Frage zurückkomme, ist C ++ effizienter in Bezug auf die Geschwindigkeit als unmanaged C ++ und warum?

    
bsobaid 10.06.2010, 16:39
quelle

8 Antworten

7

Darauf gibt es keine Antwort. Als eine wirklich allgemeine Regel wird nativer Code normalerweise schneller sein, aber 1) ist das nicht immer der Fall, 2) manchmal ist der Unterschied zu klein, um sich darum zu kümmern, und 3) wie gut der Code geschrieben ist macht normalerweise mehr Unterschied als verwaltete vs. nicht verwaltete.

Verwalteter Code wird in einer virtuellen Maschine ausgeführt. Grundsätzlich beginnen Sie mit einem Compiler, der Bytecodes als Ausgabe erzeugt und diese dann der virtuellen Maschine zuführt. Die virtuelle Maschine kompiliert sie erneut zu Maschinencode und führt diesen aus. Dies kann unter bestimmten Umständen einige echte Vorteile bieten. Für ein Beispiel, wenn Sie einen 64-Bit-Prozessor haben, der eine 64-Bit-VM ausführt (ziemlich genau eine Angabe mehr), und ein altes Programm geschrieben wurde, bevor 64-Bit-Prozessoren üblich waren, kompiliert die VM diesen Byte-Code immer noch zu 64- Bit-Maschinen-Code, der zumindest für einen gewissen Code einen beträchtlichen Geschwindigkeitsvorteil bieten kann.

Gleichzeitig kann es auch für einige Codes ein ziemlich deutlicher Nachteil sein. Insbesondere läuft der Compiler während der Benutzer wartet. Um dies zu berücksichtigen, kann der Compiler der VM selbst nicht sehr langsam laufen. Obwohl sich native Codegeneratoren unterscheiden, besteht eine recht gute Chance, dass der von Ihnen ausgewählte native Compiler mindestens einige Optimierungen enthält, auf die im Bytecode-Compiler der VM verzichtet wurde, um die Ressourcennutzung vernünftig zu halten.

Die VM verwendet auch einen Garbage Collector. Müllsammler haben eher andere Eigenschaften als die manuelle Speicherverwaltung. Bei vielen manuellen Managern ist das Zuweisen von Speicher ziemlich teuer. Das Freigeben von Speicher ist ziemlich billig, aber in etwa linear mit der Anzahl der Elemente, die Sie freigeben. Andere manuelle Manager kehren das um und machen zusätzliche Arbeit, wenn sie Speicher freigeben, um die Zuweisung schneller zu machen. In beiden Fällen unterscheidet sich die Kostenstruktur von einem typischen Kollektor.

Mit einem Garbage Collector ist das Zuweisen von Speicher typischerweise sehr billig. Bei einem typischen (kopierenden) Collector hängen die Kosten für die Freigabe von Speicher in erster Linie von der Anzahl der Objekte ab, die zugewiesen wurden und noch immer (zumindest potentiell) verwendet werden.

Die Zuweisungen selbst unterscheiden sich jedoch auch. In nativem C ++ erstellen Sie normalerweise die meisten Objekte auf dem Stapel, wobei sowohl das Zuweisen von als auch das Freigeben von Speicher extrem billig ist. In verwaltetem Code weisen Sie in der Regel einen viel größeren Prozentsatz des Arbeitsspeichers dynamisch zu, in dem die Daten gesammelt werden.

    
Jerry Coffin 10.06.2010 16:50
quelle
3

Sie können langsamen Code in jeder Sprache schreiben; Umgekehrt können Sie anständige Algorithmen verwenden, die in fast jeder Sprache schnell sein können.

Die übliche Antwort hier wäre, eine Sprache auszuwählen, die Sie bereits kennen, verwenden Sie geeignete Algorithmen, dann profilieren Sie die Hölle, um die tatsächlichen Hotspots zu bestimmen.

Ich bin etwas besorgt über die Hunderte von Ereignissen pro Millisekunde Aussage. Das ist eine Menge. Werden Sie vernünftigerweise in der Lage sein, die von Ihnen erwartete Verarbeitung in jeder Sprache durchzuführen?

Als C ++ - Entwickler auf Hochleistungssystemen traue ich meiner Fähigkeit zu, den ausgegebenen Code zu profilieren und zu optimieren. Das gesagt; Es gibt sehr leistungsfähige .NET-Anwendungen, bei denen der Verfasser große Anstrengungen unternommen hat, um die dynamische Speicherzuweisung innerhalb der kritischen Schleifen nicht durchzuführen - meist durch die Verwendung zugewiesener Pools von zuvor erstellten Objekten.

Um meinen vorherigen Kommentar zu wiederholen: Wählen Sie, was Sie bereits wissen, und stimmen Sie dann ab. Selbst wenn Sie eine Sackgasse treffen; Sie werden wahrscheinlich viel mehr über Ihren Problembereich wissen.

    
sdg 10.06.2010 16:54
quelle
2

Es hängt alles von der Situation ab.

Dinge, die nicht verwalteten Code schneller / verwalteten Code langsamer machen:

  • Der Code muss in Maschinencode konvertiert werden, bevor er ausgeführt werden kann
  • Garbage Collection kann einen Overhead verursachen
  • Aufrufe von verwaltetem zu nicht verwaltetem Code haben einen erheblichen Overhead
  • unmanaged Compiler können mehr optimieren, da sie direkt Maschinencode erzeugen (siehe mich selbst)

Dinge, die verwalteten Code schneller / nicht verwalteten Code langsamer machen:

  • Da der Code direkt vor der Verwendung in den Maschinencode konvertiert wird, kann der verwaltete Code für den tatsächlichen Prozessor optimiert werden (mit nicht verwaltetem Code müssen Sie den "minimal unterstützten" Prozessor ansprechen).

Und wahrscheinlich gibt es viele weitere Gründe.

    
Patrick 10.06.2010 17:01
quelle
2

Verwalteter Code ist in den meisten Fällen langsamer als nicht verwalteter Code, obwohl die .Net CLR vor der Ausführung des Codes immer eine JIT-Kompilierung durchführt (sie wird während der Ausführung des Programms nicht mehrfach kompiliert, interpretiert den Code jedoch nie richtig) .

Das Problem besteht eher in vielen Überprüfungen der CLR, z. um zu sehen, ob Sie über die Grenzen eines Arrays laufen, wenn Sie versuchen, darauf zuzugreifen. Dies führt zu weniger Problemen mit Pufferüberläufen usw., bedeutet aber auch einen Leistungseinbruch aufgrund des zusätzlichen Aufwands dieser Überprüfungen.

Ich habe Experimente gesehen, bei denen C # C ++ übertroffen hat, aber diese wurden mit Code ausgeführt, der die Objekthierarchien usw. stark ausnutzt. Wenn es auf Zahlenverarbeitung ankommt und Sie das Beste aus Ihrem PC herausholen wollen, müssen Sie gehen mit nicht verwaltetem Code.

Ein weiterer Punkt wurde bereits erwähnt - der GC führt zu etwas unvorhersehbaren Pausen in der Programmausführung, wenn der Speicher freigegeben werden muss. Sie benötigen diese Zeit auch, wenn Sie Speicherverwaltung in nicht verwaltetem Code ausführen, aber es tritt häufiger auf und wenn Sie sich dazu entschließen, ein Objekt zu zerstören, was bedeutet, dass es nicht für das gesamte Programm gleichzeitig erfolgt, so haben Sie keine lange Pause / p>     

Oliver Ulm 22.01.2012 22:07
quelle
0

Hier gibt es viele gute Antworten, aber ein Aspekt von verwaltetem Code, der ihm auf lange Sicht einen Vorteil verschaffen könnte, ist die Laufzeitanalyse. Da der vom verwalteten Compiler generierte Code ein Zwischenformat ist, kann der tatsächlich ausgeführte Maschinencode basierend auf der tatsächlichen Verwendung optimiert werden. Wenn eine bestimmte Untermenge von Funktionalität stark verwendet wird, kann der JIT'er den Maschinencode alle auf der gleichen Speicherseite lokalisieren, wodurch die Lokalität erhöht wird. Wenn ein bestimmter Unteraufruf wiederholt von einer bestimmten Methode ausgeführt wird, kann ein JIT'er diesen dynamisch inline einreihen.

Dies ist eine Verbesserung gegenüber nicht verwaltetem Code, bei dem Inlining im Voraus "erraten" werden muss und übermäßiges Inlining schädlich ist, da es die Code-Größe erhöht und Lokalitätsprobleme verursacht, die (sehr zeitaufwendige) L2 / L1-Cache-Misses verursachen. Diese Information ist für die statische Analyse einfach nicht verfügbar, so dass dies nur in einer JIT'ing-Umgebung möglich ist. Es gibt einen guten Korb mit möglichen Gewinnen aus der Laufzeitanalyse, wie zum Beispiel optimiertes Schleifenabwickeln, etc.

Ich behaupte nicht, dass der .NET JIT'er so schlau ist, wie er sein könnte, aber ich weiß, dass ich von globalen Analysefunktionen gehört habe und ich weiß, dass bei Hewlett-Packard eine Menge an Untersuchungen zur Laufzeitanalyse gemacht wurde und andere Firmen.

    
David Gladfelter 10.06.2010 17:30
quelle
0

Schreibe schnellen Code, ist immer ein Schmerz. Das Hauptproblem, das Sie nur für eine Plattform optimieren können. Dies ist wirklich ein Fall bei Console, Embedded oder einer anderen Plattform, auf der Hardware immer gleich ist. In der realen PC-Welt ist das nicht der Fall. Unterschiedlicher Kern, andere Konstruktion usw. machen dies zu einem Albtraum. Dies ist das Hauptproblem, ich denke, dass wirklich zwischen Mann / Unam-Code unterscheiden. Mann. Code kann optimistisch für die neue Plattform optimiert werden, wenn sie ausgeführt wird. Unman Code nicht, ist in den Stein geschrieben.

    
andreae75 20.07.2011 07:24
quelle
-1

Zuerst verarbeitet Ihre Anweisung "Hunderte von Ereignissen in jeder Millisekunde." klingt ziemlich unrealistisch. Wenn Sie kein speziell entwickeltes Taktmodul im Computer haben, glaube ich nicht, dass Sie das Ziel mit einem generischen PC erreichen können (die typische Auflösung liegt bei etwa 10 Millisekunden). Zweitens ist Native C ++ in Bezug auf die Leistung erheblich besser. Es gibt eine Menge Optimierung, die in Bezug auf C ++ beschleunigt werden kann, während es im verwalteten Code nicht möglich ist. Beachten Sie außerdem, dass die Garbage Collection im verwalteten Code die Leistung unvorhersehbar macht - wenn GC hochfährt, wird der gesamte Prozess eingefroren. Sobald Sie auf das Problem stoßen, ist die Lösung schmerzhafter, jetzt ist der "nette Stil", den der verwaltete Code bietet, verschwunden.

Was die Fähigkeit betrifft, mit der der Code für die CPU optimiert werden kann, ist dies richtig, aber Sie können die CPU-Funktionen (SSE2, MMX usw.) auch in nativem C ++ nutzen. Aufgrund meiner Erfahrung ist der Leistungsschub vernachlässigbar.

    
cuteCAT 24.11.2010 20:53
quelle
-2

Ist C ++ / CLI keine halb interpretierte Sprache wie Java?

Hat gestern auch niemand eine Studie veröffentlicht, die gezeigt hat, dass GC-Systeme immer langsamer sind als nicht GC?

    
Crazy Eddie 10.06.2010 16:49
quelle

Tags und Links