Frage

Ich plane, in der Entwicklung eines Codes in C-Sprache für Monte-Carlo-Analyse komplexer Probleme geschrieben teilzunehmen. Dieses Codes zuordnet riesige Datenfelder im Speicher um seine Leistung zu beschleunigen, damit der Autor des Codes hat sich dafür entschieden C anstelle von C ++ behaupten, dass ein schneller und zuverlässiger (in Bezug auf Speicherlecks) Code mit C.

Sind Sie einverstanden mit, dass? Was wäre Ihre Wahl sein, wenn Sie bei der Berechnung 4-16 GB Daten-Arrays im Speicher speichern müssen?

War es hilfreich?

Lösung

Auf jeden Fall C ++. Standardmäßig gibt es keinen signifikanten Unterschied zwischen den beiden, und C ++ bietet ein paar Dinge C nicht:

  1. Bauer / Destruktoren. Diese können Sie die meisten Speicherverwaltung automatisieren, Zuverlässigkeit verbessert wird.
  2. pro-Klasse Verteilern. Diese können Sie Zuordnung zu optimieren, basierend auf, wie bestimmte Objekte sind so konzipiert und / oder verwendet werden. Dies kann besonders nützlich sein, wenn Sie eine große Anzahl von kleinen Objekten benötigen (ein offensichtliches Beispiel zu geben).

Das Endergebnis ist, dass in dieser Hinsicht C stellt absolut keine Möglichkeit, einen Vorteil gegenüber C ++. Im schlimmsten Fall können Sie tun genau das gleiche Dinge auf die gleiche Weise.

Andere Tipps

Es ist ein Merkmal von C99, die von C ++ fehlt ist und dass möglicherweise gibt deutliche Geschwindigkeitsgewinne in schweren Zahlenverarbeitung Code, und das ist Schlüsselwort restrict. Wenn Sie ein C ++ Compiler verwenden können, dass dies unterstützt, dann haben Sie ein zusätzliches Werkzeug im Kit, wenn es um die Optimierung kommt. Es ist nur ein möglicher Gewinn, aber: ausreichend inlining die gleichen Optimierungen wie restrict erlauben können und vieles mehr. Es hat auch nichts mit Speicherzuweisung zu tun.

Wenn der Autor des Codes kann einen Performance-Unterschied zwischen C und C ++ Code zeigt eine 4-16GB Array Zuweisung, dann (a) Ich bin überrascht, aber OK, es gibt einen Unterschied, und (b) wie viele mal wird das Programm so großes Arrays zuweisen? Ist Ihr Programm geht tatsächlich eine erhebliche Menge seiner Zeit zur Aufteilung der Speicher zu verbringen, oder ist es die meiste Zeit verbringen zugreifenden Speicher und Berechnungen zu tun? Es dauert eine lange Zeit, um tatsächlich tun alles mit einem 4 GB-Array, verglichen mit der Zeit, es zu zuteilen nahm zu, und das bedeutet, Sie sollten über die Leistung von „etwas“, nicht die Leistung der Zuteilung besorgt werden . Sprinter kümmert sie sehr, wie schnell sie die Blöcke aus. Marathonläufer, nicht so sehr.

Sie müssen auch vorsichtig sein, wie Sie Benchmark. Sie sollten zum Beispiel malloc(size) gegen new char[size] werden verglichen. Wenn Sie malloc(size) gegen new char[size]() testen, dann ist es ein unfairer Vergleich, da die letzteren setzt den Speicher auf 0 und die ehemalige nicht. Vergleichen gegen calloc statt, aber auch zu beachten, dass malloc und calloc beide sind von C ++ in dem (unwahrscheinlichen) Fall, dass sie beweisen messbar schneller.

Letztlich aber, wenn der Autor „besitzt“ oder das Projekt gestartet, und es vorzieht, schreibt in C statt C ++, dann sollte er diese Entscheidung nicht rechtfertigen, wohl Störverhalten Ansprüche, sollte er es rechtfertigen, indem er " ich ziehe C, und das ist, was ich verwende“. Normalerweise, wenn jemand einen Anspruch, wie diese über die Sprache Leistung macht, und es stellt sich heraus auf der Prüfung nicht um wahr zu sein, Sie feststellen, dass die Leistung ist nicht der wahre Grund für die bevorzugte Sprache. die Behauptung als falsch erweisen wird nicht wirklich Ursache des Autors dieses Projektes plötzlich C beginnen mag ++.

Es gibt keinen wirklichen Unterschied zwischen C und C ++ in Bezug auf die Speicherzuweisung. C ++ Hat mehr ‚versteckte‘ Daten, wie zum Beispiel virtuelle Zeiger und so weiter, wenn Sie virtuelle Methoden auf Ihre Objekte haben wollte. Aber die Zuteilung einer Reihe von Zeichen ist genauso teuer in C, wie in C ++, in der Tat, sind sie wahrscheinlich beide malloc, es zu tun. In Bezug auf Leistung, ruft C ++ Konstruktor für jedes Objekt in dem Array. Beachten Sie, dass dies nur geschieht, wenn es einen gibt, wird der Standard-Konstruktor tut nichts und wegoptimiert.

Solange Sie Pools von Daten zu vermeiden, Speicherfragmentierung preallocating, sollten Sie gut zu gehen. Wenn Sie einfach POD-Strukturen ohne virtuelle Methoden, und ohne den Bau, gibt es keinen Unterschied.

Das einzige, was in Ungnade von C ++ ist es eine zusätzliche Komplexität ist - kombinieren, dass mit einem Programmierer, der es falsch verwendet, und Sie können leicht verlangsamen deutlich. einen C ++ Compiler ohne C ++ Funktionen können Sie Zeit die gleiche Leistung. Mit C ++ richtig, haben Sie einige posisbilities schneller zu sein.

Die Sprache ist nicht Ihr Problem , Aufteilung und durchqueren große Arrays ist.

Der Haupt tödlicher Fehler, den man bei der Zuteilung (in jeder Sprache) machen könnte, ist 16G der Zuweisung von Speicher, auf Null initialisiert wird, nur mit späteren tatsächlichen Werten zu füllen.

Die meisten Performance-Gewinne ich von algorithmischen Optimierungen erwarten würde, die Referenzlokalität verbessern.

Je nach zugrunde liegenden Betriebssystem, können Sie auch Caching-Algorithmen beeinflussen - zum Beispiel darauf hinweist, dass eine Reihe von memroy nur sequentiell verarbeitet wird.

Für Rohdaten Zuteilung, sollte es nicht ein Unterschied zwischen C und C ++ auf den meisten Systemen, wie sie in der Regel beide die gleichen Mechanismen Laufzeitbibliothek verwenden. Ich frage mich, ob dies die klassische Benchmark pitfall war, wo sie auch die Laufzeit der Konstruktoraufrufe in C gemessen ++ und bequem vergessen die Laufzeit von jeder Art von Initialisierung Code in C einschließlich.

Auch die „zuverlässiger (über Speicherlecks)“ Argument halten kein Wasser, wenn Sie RAII in C ++ verwenden (wie Sie sollte). Es sei denn, jemand mit Bezug auf die es zuverlässiger auslaufen, mit RAII, intelligente Zeiger und Containerklassen wird das Potential für Lecks verringern, nicht erhöhen.

Mein Hauptanliegen mit so viel Speicher Zuweisung doppelte wäre:

  • Wenn Sie nahe an das physischen Speicherlimit auf den Maschinen bekommen Sie zur Monte-Carlo-Simulation laufen auf, es ist eine gute Möglichkeit, die Leistung zu verringern, da die Festplatte gut dreschen kann beginnen, wenn die virtuellen Bedürfnisse Speichersystem zu starten Paging viel. Virtueller Speicher ist nicht „frei“, obwohl eine Menge Leute denken, es ist.
  • Daten Layout Bedürfnisse sorgfältig geprüft werden, um Prozessor-Cache-Nutzung zu maximieren, sonst hat man teilweise die Vorteile des Haltens die Daten im Hauptspeicher an erster Stelle verlieren.

Wenn die Speicherzuordnung zu einem Engpass in solchen Code ist, würde ich vorschlagen, eher neu zu gestalten, nicht die Sprache für eine schnellere Zuordnung zu ändern. Wenn Sie Speicher einmal vergeben und führen Sie dann eine Menge Berechnungen würde ich diese Berechnungen erwartet, dass ein Engpass. Wenn die Kosten der Zuteilung von Bedeutung ist, ist etwas falsch hier.

Sie können die C-Familie von Speicherzuordnungsfunktionen in C ++ verwenden zu. Sowohl den Standard malloc und free, realloc zum Vergrößern / Shring Arrays und alloca Speicher auf dem Stapel zuweisen

Wenn Sie mit new gehen, wird es mehr Speicher zuzuteilen als benötigt wird (vor allem während des Debuggens) und machen zusätzliche Kontrollen für Konsistenz. Es wird auch Konstruktor für Klassen aufrufen. In einer Veröffentlichung (-O3) bauen die Differenz wird für die meisten Anwendungen vernachlässigbar sein.

Nun, was new bringt, dass malloc nicht tut, ist die in-place new. Sie können einen Puffer preallocate und dann die new an Ort und Stelle benutzen, um Ihre Struktur in diesem Puffer zu setzen, also „Zuweisung“ es augenblicklich zu machen.

Alles in allem würde ich nicht bleiben, weil die Leistungsprobleme von C entfernt. Wenn überhaupt, wird Ihr Code effizienter, da Klassen der this Zeiger in Register anstelle von Parametern wie in der C-Äquivalent passieren. Ein echter Grund von C zu bleiben weg ist die Größe des C ++ Runtime. Wenn Sie Programme für eingebettete Systeme oder Boot-geladenen Programme entwickeln, können Sie die ~ 4 MB Laufzeit nicht einbetten. jedoch für normale Anwendungen, wird dies keinen Unterschied machen.

Wenn Sie 4-16 GB Daten-Arrays im Speicher speichern müssen bei der Berechnung und Ihre Maschine hat nur 2 GB physischen Speicher, was dann?

Was passiert, wenn Ihre Maschine 16 GB physischen Speicher hat? Ist das Betriebssystem keinen physischen Speicher benötigen?

Ist das Betriebssystem können Sie sogar einen Adressraum von 4 GB, 16 GB, etc?

Ich schlage vor, dass, wenn die Leistung eine primäre Umsetzung Einschränkung ist, dann zu verstehen, wie die Plattformen, die verwendet werden sollen, Funktion und führen Sie sind viel wichtiger als die Frage nach einer messbaren Leistungsdifferenz zwischen C und C ++, bei identischen Umgebungen und Algorithmen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top