Itanium, Opteron, IA64, x64 – was bedeutet das alles? (Teil 1)

Die Intersystems Inc., der Hersteller von Caché-Server, der als Basis-Datenbankserver in transObjects® Anwendung findet, erschließt mit dem Windows-Release 5.0.21 sowie dem grundlegend überarbeiteten 5.1.0 die zweite 64-Bit Windows®-Plattform neben „IA64“, nämlich das „x64“. Für uns ist es Anlass genug, den Vergleich mit Intel’s „IA64“ (Itanium®) anzustellen, den wir bis dato mangels passender Caché-Version nicht machen konnten (zwar gab es bereits seit längerem Caché-Editions für die als „Opteron“ bzw. „AMD64/EM64T“ bekannt gewordene Plattform, jedoch leider nicht unter Windows® x64).

Wir sind gespannt auf das Verhalten von Caché auf einer EM64T-Hardware, auf der Caché bereits unter dem 32-Bit-Windows® exzellent lief und wir sind neugierig auf den Vergleich zu Inte®’s „IA64“, mit dem wir bereits seit 3 Jahren unsere Erfahrungen haben machen können. Wird Caché wirklich – wie viele prophezeien – mit einem 64-Bit-Xeon auf und davon ziehen oder wird eher Intel’s behäbig wirkender Itanium® das Rennen machen? Ist der von Intersystems erstellte Build wirklich optimal auf die spezifische Itanium®-Architektur getrimmt?

Wir wollen es ganz genau wissen – von daher sind derzeit in unserem Benchmark-Labor die Ärmel richtig hochgekrempelt. Vorerst aber wollen wir uns dem „IA64 vs. x64“ mehr von der theoretischen Seite her nähern und auf dieser Basis geben wir hier eine kleine Entscheidungshilfe in Sachen Anschaffung eines 64-Bit-Servers, insbesondere dann, wenn auch der Caché-Server hierauf betrieben werden sollte. Voilà:

Während die ursprünglich von AMD entwickelte und unter „Opteron“ bekannt gewordene 64-Bit-Plattform somit einen weiteren Punkt für sich verbuchen kann und nicht zuletzt auch für transObjects®-Anwender noch ein Stück relevanter wird, kontert der Markführer Intel® mit einer Multi-Core-Variante des Itanium®-Prozessors. Der für Herbst 2003 angekündigte „Montecito“ lässt gerade eingedenk der bereits bei dem Vorgänger „Madison“ überraschenden Benchmarks für das teils schon verloren geglaubte Rennen gegen „x64“ wieder Hoffnung schöpfen.

Wir versuchen nun grundlegende Unterschiede zwischen den beiden 64-Bit-Plattformen zu charakterisieren, ferner dem transObjects®-Anwender eine Entscheidungshilfe in Sachen geeigneter Plattform für den Caché-Server zu geben. Zu Guter letzt spekulieren wir darüber, welche der beiden Plattformen á la longue das Rennen machen könnte. Dass dies sehr gewagt ist, ist uns vollkommen klar.

Im Jahre 2001 brachte Intel® nach einer gut 5-jährigen Entwicklung in Zusammenarbeit mit Hewlett-Packard seinen ersten 64-Bit-Prozessor auf den Markt. Die erste Itanium®-CPU machte dem damaligen Ruf der 64-Bit-Welt, die von PA-RISC, ALPHA, Sparc etc. geprägt war, alle Ehren. Wenn man irgendwie das Kunststück vollbracht hatte, Windows 2000 Advanced Server Limited Edition oder eine Beta-Version von Windows 2003 auf die monströse und kaum erschwingliche Hardware drauf zu packen, konnte man diesem Windows bei der Arbeit im wahrsten Sinne des Wortes zusehen… Unsere Tests mit einem Compaq ProLiant DL590/64, immerhin einem 4-Wege Itanium1, erbrachten insofern auch nichts anderes. Es war schlicht fürchterlich langsam! Intel’s interner Codename „Merced“ war da wohl keine Anspielung auf die Automarke… jedenfalls wollen wir es nicht annehmen…

Aber wie dem auch sei. Bei aller Fortschrittlichkeit der Itanium®-Architektur (dazu im Folgenden mehr) wies die als „Itanium1“ bekannt gewordene CPU zahlreiche Merkmale auf, die sie doch sehr behäbig haben wirken lassen. Dazu zählten z.B. die Taktung von 800 MHz (in unserem Compaq DL590/64’er waren es gar jeweils nur 733 MHz’ler), das hohe Voltage von 1.6V und die Chipgrösse basierend auf einer Prozesslänge von 180 nm. So sprachen wir etwas vornehmer wir von einem „niedertourigen“ Server… und weniger vornehm von einem „Wäschetrockner“: Denn die Luftmengen, die mit ohrenbetäubendem Lärm umgewälzt wurden, hätten mit Sicherheit recht gute Dienste in dieser Hinsicht leisten können!

Ja, und da war noch der völlig fehlende „on-die” Cache (sog. L3-Cache), der das Übrige tat, so dass der Betrieb von 32-Bit’er-Applikationen, z.B. von Caché-Server, schier unmöglich war und selbst Beta’s von Itanium®-Builds waren aufgrund von noch vollkommen unausgereiften Compiler-Tools (sofern es diese überhaupt gab !) vollkommen unzulänglich. So bestand für uns gar kein Zweifel daran, dass ein solches „IA64″ keine praktische Bedeutung fürs transObjects® haben wird.

Allerdings fielen unsere Tests Ende 2002 Anfang 2003 in einen Zeitraum hinein, in dem eine weitere Itanium®-CPU bereits in Einsatz war, nämlich die „Itanium2“. So konnten wir das diametral andere Verhalten eines HP Integrity mit 2 x Itanium2 je 900 MHz und 1.5 MB Cache gegenüber dem des „niedertourigen“ DL590/64’er am eigenen Leibe (oder besser gesagt an eigenen Ohren) erleben. Der unter dem internen Codenamen „McKinley“ geführte Prozessor hatte zwar gegenüber dem „Merced“ ein nur unwesentlich gemindertes Voltage, jedoch war der Gesamteindruck des HP-Integrity rx2600’er trotz seines L3-Cache und einer beinahe 10-fachen (!!!) Anzahl von Transistoren alles andere als monströs. Hewlett-Packard hat sogar mit der „ZX“-Reihe (ZX2600/ZX6000) eine Itanium-basierte Workstation konzipiert, deren Geräuschentwicklung beim Betrieb „unter dem Tisch“ einigermassen erträglich war.

Als die Itanium-Editions sowohl von Windows® 2003 als auch von Caché allmählich aus dem Beta-Stadium schlüpften, war die Geburtsstunde des IA64-Clusters im transObjects®-Datacenter nur noch eine Frage der Zeit. So kamen auch prompt die ersten Cluster-Nodes mit „McKinley’s“ im Gewande von HP-Intergrity zum Einsatz, zeitgleich mit den ersten Itanium®-Builds, des Caché-Servers.

Ein Problem stellte noch anfänglich diejenige Software dar, die damals noch nicht fürs Itanium-Windows® optimiert werden konnte und zwar immer noch mangels geeigneter Compiler. Dazu zählten immerhin auch die aus den Enterprise-Editions bekannten transObjects®-Module wie z.B. exmailPRO. Der auf dem „Die” integrierte „IA-32-Execution-Layer“ war zum Gähnen langsam und machte die Ausführung von 32-Bit-Tasks schlicht nicht praktikabel. Aber völlig getreu dem Itanium®-Prinzip kam die Lösung nicht etwa durch eine Verbesserung auf dem Layer selbst, sondern durch einen Softwareemulator (man höre und staune!), der in Zusammenarbeit von Intel®/Microsoft® entwickelt worden war und der später Bestandteil des Service Pack 1 von „MS Windows 2003 Server Itanium-Edition“ wurde! Dennoch war auch diese Abhilfe nur von sehr begrenzter Wirksamkeit, so dass eine richtige Lösung dieses Problems erst mit echten Itanium-Builds herbeigeführt werden konnte. Die Ausführung von 32-Bit-Tasks übers WOW64 („Windows-On-Windows64″) blieb unterdessen die Achillesferse des „IA64″.

In den darauffolgenden Jahren profitierten die transObjects®-Itanium®-Cluster – sowie auch immer mehr User – von weiteren Entwicklungen des Itanium®-Prozessors. Nach und nach kam die unter dem Codenamen „Madison“ entwickelte jedoch handelstechnisch weiterhin als „Itanium2“ geführte CPU zum Einsatz. Insbesondere die Reduktion des Voltage auf 1.3 Volt sowie der Fertigungslänge auf 130 nm haben diese Prozessoren insgesamt kompakter ausfallen lassen, wobei die 9 MB L3-Cache sowie die bis zu 1.7 GHz Taktung, wie Sie in der letzten Madison-Ausprägung namens „Madison 9M“ zu finden sind, mehr als ein erster Warnschuss in Richtung AMD/x64 waren. Nicht zu vergessen ist, dass ein EM64T mit 3GHz / 2MB bereits von einem dualen Madison mit je 1.5 GHz / 6 MB in unserem Benchmarking buchstäblich in Grund und Boden gefahren wurde. Was ein „Madison 9M“ oder gar ein „Montecito“ daraus machen würde, können wir erst zum späteren Zeitpunkt empirisch belegen. Vorerst wäre es reine Spekulation.

loggPROnet2003

Ein Rack des transObjects®-Datacenters Mitte 2003. Zu oberst und ganz zu unterst sind Knoten des Itanium-Clusters zu sehen.
Zu oberst McKinley und unterhalb davon ein Madison (je HP Integrity rx2600), ganz zu unterst der Meced DL590/64
.

Inwieweit derartige „Warnschüsse“ AMD wirklich tangieren können, ist indes nur schwer abzuschätzen. Denn eigentlich hat die „ewige Nummer 2“, wie sich manche ausdrücken, seit der ersten Umsetzung der genial einfachen Idee im Opteron-Prozessor fast nur Erfolge verzeichnet. Das genial einfache dabei ist schlicht das nachzumachen, was Intel seinerzeit beim Übergang vom 286’er zum 386’er vollzogen hat. Damals hat man den 16-Bit AX-Register schlicht zum 32-Bit EAX-Register „enhanced“ und schon fanden wir uns alle im 32-Bit-Adressraum wieder. Beim Opteron ist AMD ähnlich vorgegangen, wenn auch nicht von Anfang an durch die Erweiterung auf den vollen 64-Bit-Adressraum (da waren es „nur“ 48 Bit).

Der Coup dabei ist und bleibt die Abwärtskompatibilität. Konfrontiert mit einem 32-Bit-Betriebssystem versetzt sich ein AMD64 in einen passenden Modus und arbeitet mit der gewohnten Performance des 32-Bit-Teils. Die 64-Bit-Erweiterungen werden dann zwar entweder gar nicht oder nur ganz partiell genutzt, aber das ist nichts im Vergleich zu Itanium® der dann ja gar nicht läuft.

Der Aspekt des Investitionsschutzes war es wohl auch, der AMD die vielen Erfolge bescherte. Und die kamen dann wirklich Schlag auf Schlag, von Implementierung passender Betriebssysteme (Windows® nennt entsprechende Editions „x64“) über die Lizenz an den Branchenprimus Intel®, der seitdem die Opteron-Philosophie auf eigenen „Xeon’s“ unter „EM64T“ umsetzt, bis hin zur zwischenzeitlicher Eroberung des Workstation-Segments.

Insbesondere bei einem Vergleich x64 zu IA64 schien die AMD-Plattform zuweilen haushoch überlegen, vor allem dann, wenn man eine 32-Bit-Applikation laufen lies. Während auf Itanium® der bereits zuvor erwähnte IA-32-Execution-Layer die IA-64-Register auf die 32’er mühselig abbildete und durch eine aufwändige Prozedur so den IA-64-Datenfluss generierte, verfügte der AMD64 über vollwertige 32-Bit-Einheiten und brauchte nicht weiter als die 64-Bit’er links liegen zu lassen. Da wurden so manche Apologeten von „x64“ schon ein wenig selbstherrlich – verkehrte Welten!

Wie sind dann die Resultate unseres Benchmarkings zu erklären? Nun, dazu ist ein kleiner Einblick in die IA64-Architektur vonnöten.

Die Involvierung von HP in die Itanium-Entwicklung hat die Kompatibilität der neuen CPU zu PA-RISC (mit HP-UX / Unix) zur Voraussetzung gemacht. Angelehnt an das „Reduced Intruction Set“ – Prinzip dachten sich wohl die Entwickler etwas Ähnliches und… gönnten dem neuen Itanium® weder Einheiten für Gleitkomma-Division, geschweige denn für andere Funktionen. Der so gewonnene Platz auf dem Die wurde vielmehr für andere Bausätze genutzt, die fürs Caching sowie eine optimale Atomisierung resp. Parallelisierung von Vorgängen sorgen sollten. Die Grundidee dabei: Der Compiler kann weitaus exakter die Unabhängigkeit von Teiloperationen aus seinem Kontext hearus erkennen (was die Voraussetzung für eine optimale Parallelisierung ist), als es die CPU aus ihrem Berechnungskontext heraus kann! So gesehen wird hier scheinbar die „Verantwortung“ auf die Compiler-Hersteller abgewälzt. Aber das Konzept kann durchaus aufgehen, wie wir aus unseren Tests nun wissen. Welche Features es im Einzelnen sind, die dem Compiler (bzw. auch einem Entwickler) einen solch grossen Gestaltungsspielraum eröffnen, wollen wir nachfolgend kurz skizzieren, wobei der Leser genaueres der Fachliteratur entnehmen mag.

Bereits beim „Merced“ spendierte Intel® seinem Itanium®-Sprössling neben der vollen 64-Bit-Adressiereung ein rekordverdächtiges Set an Registern: 128 Allzweck-Register, weitere 128 zur Gleitkomma-Verarbeitung und 64 sog. Predicate-Register und schliesslich noch eine Vielzahl von Spezialregistern, wie 128 Applikationsregister für den Kernel und die Stack-Engine sowie Branch-, ID-, und Performance-Monitor-Register.

Mit einem solchen Register-Set kann gut jongliert, genauer gesagt, rotiert werden. Denn das Prinzip der Registerrotation mit den so genannten dynamischen Registern gehört auch zu den wichtigsten Merkmalen der IA-64-Architektur. Die aufwändigen Kopieroperationen zwischen den Registern werden auf ein Minimum reduziert, indem man – vereinfacht dargestellt – mit Registerzeigern anstatt Registern arbeitet und diese Zeiger dann, z.B. in einer Schleife, inkrementiert (hierbei soll lt. Intel® ein anderes Feature eine wichtige Rolle spielen, nämlich die Inkrementierung der Register beim Abspeichern ohne einem zusätzlichen Schritt; als C++/C-Programmierer kennen wir alle den Postinkrement-Operator). Dieses sog. Software-Pipelining, d.h. die Parallelisierung von für unabhängig erkannten Teiloperationen, indem man sie (parallel) über virtuelle Register auf unterschiedliche physikalische Register zugreifen lässt, soll beispielsweise bei der typischen Punkt-für-Punkt Bildbearbeitung deutliche Vorteile gegenüber der IA-32-Architektur aufweisen.

Natürlich besitzt der Itanium als ein superskalarer Prozessor mehrere ALU’s, weshalb sich die Parallelisierung wirklich auszahlt, so sie denn richtig gemacht ist. Folglich ist eigentlich die Parallelisierung der Begriff, denn man verwenden müsste, wenn man die IA64-Architektur mit nur einem einzigen Begriff umschreiben möchte. Und Intel® leistet in der Tat auch einiges, um diese Parallelisierung zu verfeinern. Die Technik, die Intel® im gegensatz zu PA-RISC hierfür aufbietet, ist EPIC (Explicit Parallel Instruction Computing). EPIC basiert auf dem VLIW Very-Long-Instruction-Word-Prinzip. Hierbei wird ein relativ breites Befehlswort in mehrere Teilworte unterteilt, die einzelne unabhängige Instruktionen enthalten. Die CPU liest das lange Befehlswort und leitet die darin enthaltenen Instruktionen an voneinander unabhängige Ausführungseinheiten weiter. Die Entscheidung, welche Instruktionen wirklich unabhängig sind, muss dann allerdings der Compiler treffen.

Gewiss bringt Intel® mit IA64 etwas mehr, als nur den Ball den Compiler-Herstellern zuzuspielen. Neben der zuvor erwähnten Registerrotation, die letztendlich einer Optimierung der parallelen Abarbeitung dient, wartet Itanium® mit einer Reihe von Features auf, die die problematischen Charakteristika der IA32-Architektur umgehen sollten. So lässt man beispielsweise den Itanium® Programmsprünge erahnen oder man versucht sie gar mittels sog. Predicating gänzlich zu umgehen. Ein sehr häufig bemühtes Beispiel fürs Predicating ist ein „if-else“-Block, der die bekanntermassen problematischen bedingten Sprünge impliziert. Hier lässt man zwei Recheneinheiten parallel beide Eventualitäten berechnen und trägt zum Schluss nur das Zutreffende in das entsprechende Register ein (!). Aber auch diese Möglichkeit muss der Compiler erkennen, wodurch wir noch einmal das Prinzip der IA64-Architektur vor Augen geführt bekommen.