Aus Linux-Magazin 06/2008

GNU Compiler Collection 4.3

stock photo, Imacon Color Scanner

Mit neue Optimierungen, experimenteller Unterstützung für den kommenden C++-Standard 200x, einer optional parallelisierten C++-STL und einem neuen Java-Compiler aus dem Eclipse-Projekt versucht die neue GCC-Version 4.3 die Entwicklerrechner zu erobern .

Recht schnell nach GCC 4.2 [1] steht die GNU Compiler Collection [2] jetzt in Version 4.3 bereit [3]. Erwartungsgemäß entfallen manche als veraltet markierten Funktionen, beispielsweise die Optimierungsoptionen »-m386«, »-m486«, »-mpentium« und »-mpentiumpro«. Wer die historischen CPUs unbedingt braucht, kann sie jedoch per »-march=«- und »-mtune=«-Option Compiler-mäßig reanimieren. Besitzer neuer Prozessoren dürfen sich über dedizierte Optimierungsoptionen für AMD Geode und Intel Core 2 freuen sowie von den Features SSE3 (»-msse3«), SSE 4.1 (»-msse4.1«) und SSE 4.2 (»-msse4.2«) ihrer Rechenkünstler profitieren.

Als neue Architektur kommt ARM in Version 7 hinzu, die die Erweiterung Thumb-2 für Größenoptimierungen unterstützt. Direkter Support für die IBM Synergistic Processor Unit (SPU) der Cell Broadband Engine Architecture, zu finden in der Playstation 3 und IBM-Servern, feiert mit dem neuen GCC ebenfalls Premiere. Bei Mips, Motorola 68000, Coldfire, Cris und PowerPC nennen die Release Notes [3] diverse Detailänderungen.

Einige neue Optimierungen setzen jetzt auf die MPFR-Bibliothek (Multiple-precision floating-point computations with correct rounding, [4]). Sie hilft GCC dabei, komplexere Ausdrücke und Aufrufe von eingebauten mathematischen Funktionen während der Übersetzung zu evaluieren und auf äquivalente oder konstante Ausdrücke zu kürzen. Die MPFR-Bibliothek erzeugt korrekte Resultate unabhängig von der Fließkomma-Genauigkeit und Ziel-CPU. Die neue Abhängigkeit von der MPFR- und somit von den GMP-Bibliotheken führt aber dazu, dass der Aufwand, GCC selbst cross zu kompilieren, steigt, da man diese beiden Bibliotheken mit C++ ebenfalls crosskompilieren muss.

x86-Optimierung entlarvt Kernelbug

GCC-4.3-Code für x86 erzeugt vor allen Autorepeat-Stringoperation (»REP MOV…«) keine expliziten »cld«-Instruktionen mehr, was auf einem Intel Pentium 4 bis zu 52 Taktzyklen einspart. Im gleichen Zuge flog auf, dass einige Linux- und BSD-Kernel bei der Behandlung von Signalen das Direction Flag nicht selbst zurücksetzen. Das wiederum kann dazu führen, dass der Kernel in Signal-Handlern Stringoperationen in entgegengesetzter Richtung abarbeitet und deswegen auf falsche Adressen zugreift – ein klarer Fall von Sicherheitslücke [5].

Mit Version 4.3 erkennt GCC erstmals zur Übersetzungszeit Zugriffe, die Array-Grenzen definitiv überschreiten, beispielsweise anhand gesetzter Konstanten oder Offsets. Die zuständige Option »-Warray-bounds« aktiviert sich auch mit »-Wall«.

Die neu eingeführte dezimale Fließkomma-Arithmetik [6] verleiht Finanz-, aber auch wissenschaftlichen Anwendungen eine höhere Genauigkeit. Durch die Basis 10 statt 2 runden die Operationen auch besser, beispielsweise ist das Resultat von 0,9:10 jetzt 0,09 und nicht mehr 0,089999996. Als GCC-Erweiterung können Entwickler jetzt auch Integer-Konstanten in binärer Form mit dem Präfix »0b« oder »0B« als Bit-Muster angeben. Aus der Embedded-C-Spezifikation stammt die Unterstützung für Festkomma-Datentypen, die bisher aber nur für Mips implementiert ist.

ISO-konformes C++

G++ implementiert nun weitere Teile des kommenden ISO-Standards 200x (C++0x). Die Optionen »-std=c++0x« oder »-std=gnu++0x« schalten ihn scharf [7]. G++ kennt daher jetzt Templates mit variabler Anzahl von Parametern und statische Assertions. Bei geschachtelten Templates muss der Programmierer kein Leerzeichen mehr zwischen doppelte Spitzklammern setzen:

std::vector<std::vector<int> >

Die Syntax verhinderte, dass der Compiler fälschlich einen Shift-Operator erkannte. Künftig funktioniert auch:

std::vector<std::vector<int>>

In der Praxis deutlich spürbar sind die schnelleren Übersetzungszeiten dank der Säuberung der C++-STL-Header von weniger dringenden Includes. Doch kann es dazu kommen, dass man zu seinem Code den einen oder anderen Header, etwa »limit.h«, »string.h« oder »stdlib.h«, explizit hinzufügen muss [8].

Besitzer von Multicore-CPUs werden es mögen, dass einige der STL-Klassen und -Algorithmen durch Definieren des Makros »_GLIBCXX_PARALLEL« parallelisierbar sind. Wer dagegen frühe GNU-Erweiterungen der STL wie »hash_set« oder »hash_map« in seinen Programmen benutzt, muss sich mit dem Umstand auseinandersetzen, dass G++ sie bald entfernen wird; der C++0x-Standard sieht dafür »tr1/unordered_set«, »tr1/hash_set« und Ähnliches vor.

Inline-Funktionen

Beim Inline von Funktionen berücksichtigt der neue GCC die Vergrößerung des Stacks. Fallen im Zuge von Feedback-Optimierungen Testläufe an, verwendet der C-Compiler jetzt auch die Blockgrößen der String-Operationen wie »memcpy()«, »memset()« und »bzero()«, um Code für kleine Blöcke zu erzeugen. Überhaupt sind »memcpy()« und »memset()« dahin überarbeitet, dass GCC jetzt abhängig von Blockgröße und Ziel-CPU den jeweils besten Algorithmus auswählt.

C++ und objektorientierte Nachbildungen in C profitieren von dem frühen Inline-Optimierungslauf. Das trifft besonders auf Inline-Fragmente wie »set()«- und »get()«-Methoden beim Zugriff auf Properties zu, bei denen der Funktionscode kleiner ist als der Overhead seines Aufrufs. Auch ist die automatische Vektorisierung jetzt per Default bei »-O3« aktiviert und soll mit komplexeren Schleifen klarkommen. Überhaupt ersetzen einige neue Optimierungen teilweise ältere, wenig performante Algorithmen, was zu geringeren Übersetzungszeiten führt.

Andere Kaffeesorte

Eine große Veränderungen betrifft den Java-Compiler GCJ, den die GCC-Entwickler komplett durch den Eclipse Java Compiler ersetzt haben. Durch den radikalen Wechsel steht Java 1.5 vollumfänglich zur Verfügung. Das macht es möglich, aus GCC und dem Open-JDK-Fork Iced Tea einen kompletten Java-Stack aus freier Software zu zimmern. Der Hinwendung zu Eclipse fallen einige Hilfsprogramme wie »fastjar« zum Opfer – »gjar« springt hier ein. Andere, etwa »gcjh«, sind stark umgearbeitet und kennen darum nicht mehr alle Argumente von früher.

Geschwindigkeit

Das Linux-Magazin hat die Geschwindigkeit diesmal auf einem Apple Mac Pro mit Intel Xeon, 3 GHz Takt und 8 GByte RAM getestet. Das Linux-System lief im x86-64-Bit-Modus. Erfreulich ist, dass sich die Übersetzungszeiten oft gegenüber der Vorgängerversion reduzieren. Die Abbildung 1 zeigt den Vergleich zwischen GCC 4.2 und 4.3. Nur ganz ohne Optimierung (mit dem Schalter »-O0«) ist der neue Compiler durchgängig langsamer.

Die resultierenden Programme laufen in der Regel etwas schneller – die Benchmarks in Abbildung 2 zeigen eine Verbesserung im Nachkomma-Bereich. Die in der vorigen Version entstandene Regression bei der Optimierung auf Programmgröße (»-Os«) scheint behoben, was vermutlich der angesprochenen Inline-Heuristik zu verdanken ist. (jk)

Abbildung 1: Vergleich der Kompilierzeiten zwischen GCC 4.2 und der neuen Version 4.3.: Oft besser, aber auch mal schlechter. Außer bei den Compilerläufen ohne Optimierung (»-O0«-Schalter) spart der Neuling bei manch anderer Gelegenheit Arbeitszeit.

Abbildung 1: Vergleich der Kompilierzeiten zwischen GCC 4.2 und der neuen Version 4.3.: Oft besser, aber auch mal schlechter. Außer bei den Compilerläufen ohne Optimierung (»-O0«-Schalter) spart der Neuling bei manch anderer Gelegenheit Arbeitszeit.

Abbildung 2: Fünf mit den beiden GCC-Versionen übersetzte Benchmark-Programme. Die meisten Verbesserungen sind kaum messbar. Beim Optimieren auf Programmgröße (»-Os«-Schalter) beseitigt GCC 4.3 die negativen Ausreißer der Vorversion.

Abbildung 2: Fünf mit den beiden GCC-Versionen übersetzte Benchmark-Programme. Die meisten Verbesserungen sind kaum messbar. Beim Optimieren auf Programmgröße (»-Os«-Schalter) beseitigt GCC 4.3 die negativen Ausreißer der Vorversion.

Infos

[1] René Rebe, “GNU Compiler Collection 4.2”: Linux-Magazin 08/07, S. 102

[2] GCC: [http://gcc.gnu.org]

[3] Veränderungen gegenüber dem Vorgänger: [http://gcc.gnu.org/gcc-4.3/changes.html]

[4] MPFR-Bibliothek: [http://www.mpfr.org]

[5] Direction Flag Handling im Linux-Kernel: [http://nvd.nist.gov/nvd.cfm?cvename=CVE-2008-1367]

[6] Dezimale Fließkomma-Arithmetik: [http://www2.hursley.ibm.com/decimal/]

[7] C++ 200x (0x), Status: [http://gcc.gnu.org/gcc-4.3/cxx0x_status.html]

[8] Übersicht von Quellcode-Anpassungen für GCC 4.3: [http://gcc.gnu.org/gcc-4.3/porting_to.html]

Der Autor

René Rebe ist Geschäftsführer der Exactcode GmbH in Berlin und durch tägliche Arbeit mit Linux in viele Open-Source-Projekten involviert.

LINUX-MAGAZIN KAUFEN
EINZELNE AUSGABE Print-Ausgaben Digitale Ausgaben
ABONNEMENTS Print-Abos Digitales Abo
TABLET & SMARTPHONE APPS Readly Logo
E-Mail Benachrichtigung
Benachrichtige mich zu:
0 Kommentare
Älteste
Neuste Beste Bewertung
Inline Feedbacks
Alle Kommentare anzeigen
Nach oben