Der Zwischenstopp bei Version 8.1 rüstete den Intel-Compiler ICC [1] für die AMD64/x86-64-Architektur auf (bei Intel EM64T). Nun erscheint mit Version 9 eine ausgewachsene Major-Release mit neuen Erweiterungen und Optimierungen [2]. Wie in der vorherigen Version beherrscht der Compiler die Architekturen IA-32, x86-64 sowie Intel Itanium. Ein Intel-eigener Debugger, ein Code-Coverage-Tool und die Entwicklungsumgebung Eclipse runden das Paket ab. Für den Itanium-Prozessor ist zusätzlich ein Assembler enthalten, der in diesem Artikel aber nicht getestet wird. Zudem muss der Itanium-Entwickler bislang auf Eclipse-Integration verzichten.
Das Lizenzmodell gleicht dem der Vorversionen: Für Open-Source-Projekte ist eine nicht-kommerzielle Lizenz ohne Support erhältlich. Damit erstellte Binaries dürfen nicht verkauft werden. Jede kommerzielle Entwicklung erfordert eine entsprechende Lizenz. Je nach Umfang der Installation gibt man entweder die Seriennummer oder eine Lizenzdatei an. Alternativ arbeitet der Compiler auch mit einem Flex-Lizenzmanager im Netzwerk zusammen. Der C++-Compiler kostet bei deutschen Distributoren ungefähr 300 Euro, direkt bei Intel knapp 400 US-Dollar.
Profilgesteuert optimieren
Ein neues, schon im Vorfeld heiß diskutiertes Feature ist Software-based Speculative Pre-Computation (SSP) mit der zugehörigen Option »-ssp«. Dabei fügt der Compiler dem Programm einige Hilfs-Threads hinzu, die im Programm enthaltene Instruktionen vorab ausführen, um unter anderem den Instruktions-Cache der CPU mit Daten zu füllen. Besonders effektiv soll diese Methode mit Hyper-Threading arbeiten.
Das ist nur eine von mehreren so genannten profilgeleiteten Optimierungen (Profile Guided Optimizations). Dabei übersetzt der Entwickler zuerst das Programm mit spezieller Instrumentierung (»-prof-gen-sampling«), um es dann mit »profrun« auf einem repräsentativen Satz von Eingabedaten laufen zu lassen. Anschließend übersetzt er mit den gesammelten Informationen das Programm noch einmal neu, siehe [3].
Im Gegensatz zu vorherigen Versionen sind nun schon ab »-O2« standardmäßig diverse interprozedurale Optimierungen eingeschaltet und der Compiler optimiert eine größere Anzahl an Schleifen. Dabei gibt ICC jetzt noch mehr Feedback an den Entwickler: Die Reports über optimierte Schleifen und andere Warnungen sind nun detaillierter. Beim Übersetzen von mehreren Dateien bietet der Compiler mehr Möglichkeiten der Optimierung. Außerdem lassen sich in der neuen Ausgabe beim zusammengefassten Kompilieren mehrerer Dateien mit »-ipo« einzelne Objektdateien generieren.
Installation mit RPM
Die Version 8 des Intel-Compilers brachte schon 65 MByte auf die Waage, die aktuelle übertrifft dies mit satten 192 MByte bei weitem. Der Tarball enthält verschiedene RPM-Pakete für I-386, EM64T und IA64. Zusätzlich bringt er die gesamte Eclipse-Plattform mit dem C Development Toolkit (CDT) in einer GTK- sowie einer Motif-Version mit.
Ein Shellskript erledigt die Paketinstallation, die jedoch jenseits der von Intel vorgesehenen RPM-basierten Distributionen (Red Hat und Suse) durchaus Schwierigkeiten bereiten kann. Auf manchen Systemen gibt das Skript nur aus, dass es Maschinentyp, Glibc und Kernel nicht erkennt. Bei dem Debian-basierten Ubuntu verlief die Installation dagegen problemlos. Für das Entpacken der RPM-Archive ist in jedem Fall der Befehl »rpm« zuständig.
Abbildung 1: Das Frontend des Intel-Compilers ist funktional, besticht aber nicht gerade durch Modernität.
Überhaupt ist die Handhabung des Compilers nicht ganz so reibungslos, wie man es vom gut ins System integrierten GCC gewohnt ist. Standardmäßig sucht der ICC nicht in den Bibliotheks- und Header-Verzeichnissen seiner eigenen Installation, sodass in vielen Fällen »-I/opt/intel/cc/9.0/include« und gegebenenfalls »-I/opt/intel/cc/9.0/include/c++« zu setzen ist. Da die Programme im Normalfall gegen die ICC-Runtime-Bibliotheken linken, empfiehlt es sich, beim Ausführen die Umgebungsvariable »LD_LIBRARY_PATH« auf »/opt/intel/cc/9.0/lib« zu setzen.
|
OpenMP [4] ist ein umfangreicher Standard, der die Sprachen C, C++ und Fortran um Ausdrücke erweitert, die dem Compiler explizit vorgeben, wie er ein Programm in parallele Threads aufteilen soll.
Zentrale Elemente sind »#pragma«-Anweisungen, die Hinweise dafür liefern, wie der Compiler den Code in nebenläufige Fragmente zerlegen kann. So markiert »#pragma omp parallel« einen Block zur parallelen Ausführung; »shared()« spezifiziert dabei gemeinsame Variablen und »private()« die für jeden Prozess exklusiv zu behandelnden.
Der Ausdruck »#pragma omp for schedule« bestimmt die Verteilung auf die Threads. Auf diese Weise wird mittels der »#pragma«-Direktiven eine Daten verarbeitende Schleife zur parallelen Ausführung markiert.
Die Threads teilen sich dabei die Variablen »a«, »b«, »c« und »chunk«, die Iterationsvariable »i« ist privat in jedem Thread vorhanden. Der Ausdruck weist den Compiler an, die For-Schleife parallel auszuführen und den Iterationsraum dabei in einzelne Blöcke der Größe »chunk« zu zerlegen.
OpenMP definiert noch wesentlich mehr Anweisungen, um komplexe Details zur Parallelisierung vorzugeben. Zurzeit werden diese jedoch nur von speziellen Compilern implementiert, hauptsächlich im Bereich von High-Performance-Clustern. Listing 1 zeigt ein kleines Beispiel für die Verwendung von OpenMP.
|
Normalerweise erfolgt das über »source /opt/intel/cc/9.0/bin/iccvars.sh«, und zwar entweder zur Datei ».profile« hinzugefügt oder manuell auf der Konsole eingegeben. Zur Vereinfachung lassen sich diese Vorgaben in den beiden Konfigurationsdateien ».../bin/icc.cfg« sowie ».../bin/icpc.cfg« einstellen. Das regelmäßige Setzen von »LD_LIBRARY_PATH« erspart ein entsprechender Eintrag in »/etc/ld.so.conf«. Standardmäßig verwendet ICC die C++-Systembibliothek, bringt aber auch eine eigene Implementierung mit. Die Optionen -»cxxlib-icc« und -»cxxlib-gcc« erlauben das explizite Umschalten.
Seit Version 8.1 versteht ICC auch die Optionen »-march« und »-mcpu« des GNU-Compilers. Intel selbst verwendet allerdings die etwas kryptische Notation »-x{K|W|N|B|P}«, die auf den Intel-internen Codenamen basiert: K steht für Pentium III (Katmai), B für Pentium M (Banias). Die Option »-ax« verarbeitet sogar mehr als einen CPU-Typ: Damit übersetzt ICC lohnende Code-Passagen mehrfach, jeweils für eine andere CPU optimiert. Beim Start des Programms aktivieren sich abhängig vom Prozessor die passend optimierten Blöcke.