Was ist der Unterschied zwischen sjlj vs zwerg vs seh?

147

Ich kann nicht genügend Informationen finden, um zu entscheiden, welchen Compiler ich zum Kompilieren meines Projekts verwenden soll. Es gibt mehrere Programme auf verschiedenen Computern, die einen Prozess simulieren. Unter Linux verwende ich GCC. Alles ist großartig. Ich kann Code optimieren, er kompiliert schnell und verwendet nicht so viel Speicher.

Ich mache meinen eigenen Benchmark mit MSVC- und GCC-Compilern. Später werden etwas schnellere Binärdateien erstellt (für jede Unterarchitektur). Die Kompilierungszeit ist jedoch viel länger als bei MSVC.

Also habe ich mich für MinGW entschieden. Es kann jedoch keine Erklärung zu Ausnahmebehandlungsmethoden und deren Implementierung in MinGW gefunden werden. Ich kann verschiedene Distributionen für verschiedene Betriebssysteme und Architekturen verwenden.

Überlegungen:

  • Kompilierungszeit und Speicher sind für meine Verwendung nicht wichtig. Wichtig ist nur die Laufzeitoptimierung. Ich brauche meine Programme, um schnell genug zu sein. Ein langsamer Compiler ist akzeptabel.
  • Betriebssystem: Microsoft Windows XP / 7/8 / Linux
  • Architektur: Intel Core i7 / Core2 / und ein sehr alter i686 mit XP: P.
sorush-r
quelle
5
Ich bin überrascht, dass gcc schnelleren Code als MSVC produziert. Dinge müssen sich in den letzten Jahren geändert haben ...
Trojanfoe
19
@trojanfoe Mir wurde so oft gesagt, dass ich MSVC anstelle von MinGW verwenden soll. Jeder denkt, MSVC ist schneller! Ich habe MinGW 7.2 und MSVC 2010 mit einem einfachen CPU-Burst-Programm getestet. Auf corei7 mit -O3 -mtune=corei7GCC ist 45% schneller als MSVC
sorush-r
5
Nach meiner eigenen Erfahrung waren sowohl MSVC als auch Intel C ++ mit einem Schachzuggenerator (der Bitboards verwendete) 10% schneller als gcc, aber das war vor 2 Jahren ...
trojanfoe
2
@ Wolf In dieser Zeit bedeutete 45% schneller 45% weniger Zeit für die Ausführung für mich. Wenn ich mich richtig erinnere, betrug die Ausführungszeit unserer Software zur Modellierung der molekularen Geometrie für einen bestimmten Test 134 s (gcc) und 194 s (msvc). Trotzdem halte ich meine Messmethode jetzt für falsch und unzureichend (:
sorush-r
2
@ sorush-r Ich verstehe, Sie haben (194-134) / 134 berechnet, was nahe 45% liegt, danke.
Wolf

Antworten:

109

Es gibt eine kurze Übersicht im MinGW-w64 Wiki :

Warum unterstützt mingw-w64 gcc Dwarf-2 Exception Handling nicht?

Die Dwarf-2 EH- Implementierung für Windows ist überhaupt nicht für 64-Bit-Windows-Anwendungen ausgelegt. Im Win32-Modus kann der Ausnahmebehandlungs-Handler nicht über nicht dw2-fähigen Code weitergegeben werden. Dies bedeutet, dass jede Ausnahme, die nicht dw2-fähigen "Fremdrahmen" -Code durchläuft, fehlschlägt, einschließlich Windows-System-DLLs und DLLs, die mit Visual Studio erstellt wurden. Der Dwarf-2-Abwicklungscode in gcc überprüft die x86-Abwickelbaugruppe und kann ohne andere Informationen zum Abwickeln von Dwarf-2 nicht fortfahren.

Die SetJump LongJump- Methode zur Ausnahmebehandlung funktioniert in den meisten Fällen sowohl unter win32 als auch unter win64, mit Ausnahme allgemeiner Schutzfehler. Um die Schwächen von dw2 und sjlj zu überwinden, wird eine strukturierte Unterstützung für die Ausnahmebehandlung in gcc entwickelt. Unter win64 werden die Abwicklungsinformationen im xdata-Abschnitt abgelegt, und anstelle des Stapels befindet sich die .pdata (Funktionsbeschreibungstabelle). Für win32 befindet sich die Handlerkette auf einem Stapel und muss durch echten ausgeführten Code gespeichert / wiederhergestellt werden.

GCC GNU über Ausnahmebehandlung :

GCC unterstützt zwei Methoden zur Ausnahmebehandlung (EH):

  • DWARF-2 (DW2) EH , für das DWARF-2 (oder DWARF-3) -Debugging-Informationen verwendet werden müssen. DW-2 EH kann dazu führen, dass ausführbare Dateien leicht aufgebläht werden, da große Abwicklungstabellen für den Aufrufstapel in den ausführbaren Dateien enthalten sein müssen.
  • Eine Methode, die auf setjmp / longjmp (SJLJ) basiert . SJLJ-basiertes EH ist viel langsamer als DW2 EH (bestraft sogar die normale Ausführung, wenn keine Ausnahmen ausgelöst werden), kann jedoch für Code verwendet werden, der nicht mit GCC kompiliert wurde oder der keine Informationen zum Abwickeln des Aufrufstapels enthält.

[...]

Strukturierte Ausnahmebehandlung (SEH)

Windows verwendet einen eigenen Ausnahmebehandlungsmechanismus, der als strukturierte Ausnahmebehandlung (SEH) bezeichnet wird. [...] Leider unterstützt GCC SEH noch nicht. [...]

Siehe auch:

ollo
quelle
7
Danke für die Links. Ich werde DW2 für 32bit und SEH für 64 verwenden. SEH ist in mingwbuilds (4.8) verfügbar. Soll ich auf die stabile Veröffentlichung von 4.8 warten oder ist es in Ordnung? Es wird hier kompiliert. Ich mache derzeit Abhängigkeiten von meinem Projekt mit 4.8 mit SEH. Noch keine Probleme ...
Sorush-R
2
Alle Abhängigkeiten (einschließlich Boost-Bibliothek, OpenSSL, ICU, freeGLUT) wurden kompiliert, aber Qt führt zu vielen internen Compilerfehlern. Ich denke, ich werde auf die stabile Veröffentlichung von 4.8 warten
sorush-r
Haben Sie Binärdateien von qt verwendet oder selbst kompiliert?
4
@Woreos Ich benutze meinen eigenen Qt-Build. Ich fand, dass es weder mit Qt noch mit GCC 4.8 ein Problem gab. Es war mein halb verbrannter RAM! 1 Jetzt funktioniert alles gut
sorush-r
82

SJLJ (setjmp / longjmp): - Verfügbar für 32-Bit und 64-Bit - nicht "Zero-Cost": Selbst wenn eine Ausnahme nicht ausgelöst wird, führt dies zu einer geringfügigen Leistungseinbuße (~ 15% bei ausnahmeintensivem Code) - erlaubt Ausnahmen zB Windows-Rückrufe durchlaufen

DWARF (DW2, dwarf-2) - nur für 32 Bit verfügbar - kein permanenter Laufzeit-Overhead - erfordert, dass der gesamte Aufrufstapel zwergfähig ist, was bedeutet, dass Ausnahmen nicht über z. B. Windows-System-DLLs geworfen werden können.

SEH (Zero Overhead Exception) - ist für 64-Bit-GCC 4.8 verfügbar.

Quelle: http://qt-project.org/wiki/MinGW-64-bit


quelle
2
Entschuldigung, Quelllink wurde hinzugefügt.
2
Danke für deine Antwort;)
sorush-r
14
Jetzt, im Jahr 2016, können wir diese Frage zur Ruhe bringen und einfach immer SEH verwenden.
Rustyx
6
@RustyX Nur wenn Ihr Ziel x86_64 ist
sohnryang
Also Zwerg für x86?
Banguru