Es wird allgemein behauptet, dass die Itanium 64-Bit-Prozessorarchitektur von Intel fehlgeschlagen ist, weil der revolutionäre EPIC-Befehlssatz nur sehr schwer zu kompilieren war, was einen Mangel an guten Entwicklertools für IA64 und einen Mangel an Entwicklern zur Erstellung von Programmen für die Architektur bedeutete , und so wollte niemand Hardware ohne viel Software dafür verwenden, und so scheiterte die Plattform und alles aus Mangel anein Hufeisennagel gute Compiler.
Aber warum war das Compiler-Zeug so ein schwieriges technisches Problem? Mir scheint, wenn es für Compiler-Anbieter schwierig war, die explizite Parallelität in EPIC zu implementieren, warum sollte man sie dann überhaupt belasten? Es ist nicht so, als ob es eine gute, gut verstandene Lösung für dieses Problem nicht schon gegeben hätte: Belasten Sie stattdessen Intel und geben Sie den Compilern ein einfacheres Ziel.
Itanium erschien 1997. Zu diesem Zeitpunkt war das UCSD-P-Code- Bytecodesystem fast 20 Jahre alt, die Z-Maschine etwas jünger, und die JVM war der heiße neue aufstrebende Stern in der Welt der Programmiersprachen. Gibt es einen Grund, warum Intel keine "einfache Itanium-Bytecode-Sprache" angegeben und ein Tool zur Verfügung gestellt hat, das diesen Bytecode in optimierten EPIC-Code umwandelt und dabei sein Fachwissen als derjenige nutzt, der das System ursprünglich entworfen hat?
Antworten:
Wie ich mich damals erinnere, handelte es sich nicht nur um die Details von IA64, sondern auch um die Konkurrenz zum x86-64-Befehlssatz von AMD. Durch die Abwärtskompatibilität der Architektur mit dem x86-Befehlssatz konnte AMD die vorhandenen Tools und Entwicklerfähigkeiten nutzen. AMDs Schritt war so erfolgreich, dass Intel (und Via) im Wesentlichen gezwungen waren, die x86-64-Architektur zu übernehmen.
Die große Barriere war zu dieser Zeit 4 GB RAM auf Desktop-PCs (realistischer ~ 3,4 GB für Windows). x86-64 hat diese Barriere gesprengt und jedem mehr Power-Computing eröffnet. Wäre AMD nicht auf x86-64 gekommen, wäre Intel sicher froh gewesen, wenn jeder, der auf 4 GB + RAM umsteigen wollte, jahrelang eine hohe Prämie für dieses Privileg gezahlt hätte. Es hat Jahre gedauert, bis Anwendungen 64-Bit-Multithread-Programme abrufen konnten, und selbst jetzt sind 4 GB RAM Standard bei Low-End-PCs.
Kurz gesagt, Intel hat versucht, einen revolutionären Sprung mit der IA64-Architektur zu machen, und AMD hat mit x86-64 einen Evolutionsschritt gemacht. In einem etablierten Markt werden evolutionäre Schritte, die es Wissensarbeitern ermöglichen, vorhandene Fähigkeiten zu nutzen, revolutionäre Schritte gewinnen, bei denen jeder neue Fähigkeiten erlernen muss. Unabhängig von den qualitativen Unterschieden zwischen den Architekturen konnte IA64 die Dynamik seiner eigenen x86-Plattform nicht überwinden, nachdem AMD die x86-64-Erweiterungen hinzugefügt hatte.
Ich kaufe nicht die Erklärung, dass IA64 zu schwierig zu programmieren war. Es war nur schwierig im Vergleich zu den Alternativen. @delnans Argument zu Low-Level-IR ist klasse, ich glaube nur nicht, dass es einen Unterschied gemacht hätte.
Wer weiß, warum Intel nicht versucht hat, diese Last selbst zu tragen? Sie waren damals die Marktmacht. AMD war eine Bedrohung, aber Intel war der König des Hügels. Vielleicht dachten sie, IA64 wäre so viel besser als alles andere, dass sie den gesamten Markt bewegen könnten. Vielleicht haben sie versucht, eine Premium-Stufe zu erreichen und AMD, VIA usw. in der zweiten Stufe zu belassen, wo es um Rohstoffhardware mit niedrigen Margen geht - eine Strategie, die sowohl Intel als auch Apple recht erfolgreich eingesetzt haben.
War Itanium ein bewusster Versuch, eine Premium-Plattform zu schaffen und den Teppich unter AMD, VIA usw. herauszuholen? Natürlich funktioniert das Geschäft so.
quelle
Der Wikipedia-Artikel über EPIC hat bereits die vielen Gefahren umrissen, die VLIW und EPIC gemeinsam haben.
Wenn jemand den Sinn des Fatalismus in diesem Artikel nicht erkennt, möchte ich Folgendes hervorheben:
Mit anderen Worten, jedes Hardware-Design, das die (*) nicht deterministische Latenz des Speicherzugriffs nicht bewältigt, wird zu einem spektakulären Fehler.
(*) Durch "Bewältigen" ist es notwendig, eine einigermaßen gute Ausführungsleistung (mit anderen Worten "kostengünstig") zu erzielen, die es erforderlich macht, die CPU nicht so oft für Dutzende bis Hunderte von Zyklen in den Leerlauf fallen zu lassen.
Beachten Sie, dass die von EPIC eingesetzte Bewältigungsstrategie (im oben verlinkten Wikipedia-Artikel erwähnt) das Problem nicht tatsächlich löst. Es heißt lediglich, dass die Last der Anzeige der Datenabhängigkeit jetzt beim Compiler liegt. Das ist gut; Der Compiler verfügt bereits über diese Informationen, sodass es für den Compiler unkompliziert ist, diese einzuhalten. Das Problem ist, dass die CPU über einen Speicherzugriff noch einige zehn bis hundert Zyklen im Leerlauf läuft. Mit anderen Worten, es wird eine Nebenverantwortung ausgelagert, während die Hauptverantwortung immer noch nicht bewältigt wird.
Die Frage kann wie folgt umformuliert werden: "Bei einer Hardwareplattform, die zum Scheitern verurteilt ist, warum (1) nicht (2) konnten die Compiler-Autoren keine heldenhaften Anstrengungen unternehmen, um sie einzulösen?"
Ich hoffe, dass meine Neuformulierung die Antwort auf diese Frage offensichtlich macht.
Es gibt einen zweiten Aspekt des Scheiterns, der ebenfalls schwerwiegend ist.
Bei den Coping-Strategien (die im selben Artikel erwähnt werden) wird davon ausgegangen, dass softwarebasiertes Prefetching verwendet werden kann, um mindestens einen Teil des Leistungsverlusts aufgrund nicht deterministischer Latenz beim Speicherzugriff wiederherzustellen.
In der Realität ist das Prefetching nur dann rentabel, wenn Sie Streaming-Vorgänge ausführen (indem Sie den Speicher sequentiell oder mit hoher Vorhersagbarkeit lesen).
(Das heißt, wenn Ihr Code häufig auf einige lokalisierte Speicherbereiche zugreift, hilft das Zwischenspeichern.)
Die meisten allgemeinen Softwareprogramme müssen jedoch zahlreiche zufällige Speicherzugriffe durchführen. Wenn wir die folgenden Schritte betrachten:
Bei den meisten Allzweckprogrammen müssen diese drei Programme schnell hintereinander ausgeführt werden. Mit anderen Worten, es ist nicht immer möglich (im Rahmen der Softwarelogik), die Adresse im Voraus zu berechnen oder genügend Arbeit zu finden, um die Stände zwischen diesen drei Schritten zu füllen.
Um zu erklären, warum es nicht immer möglich ist, genügend Arbeit zu finden, um die Stände zu füllen, kann man sich dies folgendermaßen vorstellen.
(*) Wenn wir jemals
NOP
nützliche Arbeit leisten könnten ...Moderne CPUs versuchen, mit dynamischen Informationen mit dem gleichen Problem umzugehen, indem sie gleichzeitig den Fortschritt der einzelnen Befehle verfolgen, während sie durch die Pipelines zirkulieren. Wie ich oben erwähnt habe, ist ein Teil dieser dynamischen Informationen auf nicht deterministische Speicherlatenz zurückzuführen, daher können Compiler keinen Grad an Genauigkeit vorhersagen. Im Allgemeinen sind zum Zeitpunkt der Kompilierung einfach nicht genügend Informationen verfügbar, um Entscheidungen zu treffen, die diese Stände möglicherweise füllen könnten.
Als Antwort auf die Antwort von AProgrammer
Es ist nicht so, dass "Compiler ... das Extrahieren von Parallelität schwierig ist".
Die Neuordnung von Speicher- und Rechenanweisungen durch moderne Compiler ist der Beweis, dass es kein Problem gibt, Operationen zu identifizieren, die unabhängig und somit gleichzeitig ausführbar sind.
Das Hauptproblem besteht darin, dass eine nicht deterministische Speicherlatenz bedeutet, dass jede "Befehlspaarung", die für den VLIW / EPIC-Prozessor codiert wurde, durch den Speicherzugriff blockiert wird.
Die Optimierung von Anweisungen, die nicht blockieren (nur Register, arithmetisch), hilft nicht bei Leistungsproblemen, die durch Anweisungen verursacht werden, die sehr wahrscheinlich blockieren (Speicherzugriff).
Dies ist ein Beispiel für die Nichtanwendung der 80-20-Optimierungsregel: Die Optimierung von bereits schnellen Dingen führt zu keiner wesentlichen Verbesserung der Gesamtleistung, es sei denn, die langsameren werden ebenfalls optimiert.
Antwort von Basile Starynkevitch
Es ist nicht "... (was auch immer) schwierig", sondern EPIC ist für jede Plattform ungeeignet, die mit einer hohen Dynamik der Latenz fertig werden muss.
Wenn ein Prozessor beispielsweise über Folgendes verfügt:
Dann passt VLIW / EPIC gut zusammen.
Wo findet man solche Prozessoren? DSP. Und hier hat sich VLIW etabliert.
Im Nachhinein ist das Scheitern von Itanium (und die anhaltende Ausweitung der Forschungs- und Entwicklungsanstrengungen trotz offensichtlicher Beweise) ein Beispiel für ein organisatorisches Scheitern und verdient eine eingehende Untersuchung.
Zugegeben, die anderen Vorhaben des Anbieters wie Hyperthreading, SIMD usw. scheinen sehr erfolgreich zu sein. Möglicherweise hat die Investition in Itanium die Fähigkeiten der Ingenieure bereichert und es ihnen ermöglicht, die nächste Generation erfolgreicher Technologien zu entwickeln.
quelle
TL; DR: 1 / Es gibt andere Aspekte beim Versagen von Itanium als die Compiler-Probleme, und sie können durchaus ausreichen, um es zu erklären. 2 / a Byte Code hätte die Compilerprobleme nicht gelöst.
Nun, sie waren auch spät dran (geplant für 98, erste Auslieferung im Jahr 2001) und als sie schließlich die Hardware ausliefen, bin ich mir nicht mal sicher, ob sie das für den früheren Zeitpunkt versprochene Ergebnis lieferte (IIRC, sie ließen zumindest einen Teil der Hardware fallen) x86-Emulation (ursprünglich geplant), daher bin ich mir nicht sicher, ob die Kompilierungsprobleme erfolgreich waren, auch wenn sie gelöst wurden (und AFAIK noch nicht). Der Compiler-Aspekt war nicht der einzige Aspekt, der zu ehrgeizig war.
Ich bin nicht sicher, wo Sie das Werkzeug platzieren.
Wenn es sich um einen Prozessor handelt, haben Sie nur eine andere Mikroarchitektur und es gibt keinen Grund, x86 nicht als öffentlichen ISA zu verwenden (zumindest für Intel sind die Kosten für die Inkompatibilität höher als für einen saubereren öffentlichen ISA).
Wenn es extern ist, ist es noch schwieriger, mit einem Bytecode zu beginnen, als mit einer höheren Sprache. Das Problem bei EPIC ist, dass es nur die Parallelität verwenden kann, die ein Compiler finden kann, und dass es schwierig ist, diese Parallelität zu extrahieren. Wenn Sie die Sprachregeln kennen, haben Sie mehr Möglichkeiten, als wenn Sie durch bereits geplante Aktionen eingeschränkt werden. Meine (zugegebenermaßen unzuverlässige und von jemandem, der diese von weitem verfolgte) Erinnerung ist, dass HP (*) und Intel auf der Compiler-Front nicht die Sprachniveau-Extraktion der Parallelität erreicht haben, nicht das niedrige Niveau, das in einem Byte vorhanden gewesen wäre Code.
Vielleicht unterschätzen Sie die Kosten, zu denen der aktuelle Prozessor seine Leistung erbringt. OOO ist effektiver als die anderen Möglichkeiten, aber es ist sicherlich nicht effizient. EPIC wollte das Flächenbudget, das für die Implementierung von OOO verwendet wurde, nutzen, um mehr Raw-Computing bereitzustellen, in der Hoffnung, dass Compiler in der Lage sein würden, davon Gebrauch zu machen. Wie oben beschrieben, können wir nicht nur - wie AFAIK - noch immer keine Compiler mit dieser Fähigkeit schreiben, sondern der Itanium hat auch genug andere schwer zu implementierende Funktionen, die noch zu spät waren und die noch nicht so leistungsfähig waren sogar wettbewerbsfähig (außer vielleicht in einigen Nischenmärkten mit viel FP-Berechnung) mit dem anderen High-End-Prozessor, wenn er nicht mehr so gut läuft.
(*) Sie scheinen auch die HP-Rolle in EPIC zu unterschätzen.
quelle
Ein paar Dinge.
Zum einen war IPF in Ordnung. Dies bedeutete, dass Sie sich nicht auf eine Nachbestellung verlassen konnten, um sich im Falle eines Cache-Fehlschlags oder eines anderen lang andauernden Ereignisses zu retten. Infolgedessen mussten Sie sich auf spekulative Funktionen verlassen - nämlich auf spekulative Lasten (Lasten, die ausfallen durften -, wenn Sie nicht wussten, ob Sie ein Ladeergebnis benötigen würden) und auf erweiterte Lasten (Lasten, die ausreichen könnten) Führen Sie den Vorgang mit dem Wiederherstellungscode erneut aus, wenn eine Gefahr aufgetreten ist. Es gab auch Hinweise zum Abrufen von Zweigen und Caches, die nur von einem Assembler-Programmierer oder mithilfe der profilgesteuerten Optimierung intelligent verwendet werden konnten, im Allgemeinen nicht mit einem herkömmlichen Compiler.
Andere Maschinen zu der Zeit - nämlich UltraSPARC - waren in Ordnung, aber IPF hatte auch andere Überlegungen. Einer war das Codieren von Speicherplatz. Itanium-Anweisungen waren von Natur aus nicht besonders dicht - ein 128-Bit-Bundle enthielt drei Operationen und ein 5-Bit-Template-Feld, in dem die Operationen im Bundle beschrieben wurden und ob sie alle zusammen ausgegeben werden konnten. Dies führte zu einer effektiven Operationsgröße von 42,6 Bit - im Vergleich zu 32 Bit für die meisten kommerziellen RISC-Operationen zu der Zeit. (Dies war vor Thumb2 et al. - RISC bedeutete immer noch Steifigkeit mit fester Länge.) Schlimmer noch, Sie hatten nicht immer genug ILP, um die von Ihnen verwendete Vorlage anzupassen Vorlage oder das Bundle. In Kombination mit der vorhandenen relativ geringen Dichte bedeutete dies, dass eine anständige Trefferquote im i-Cache a) wirklich wichtig war.
Während ich immer das Gefühl hatte, dass das Argument "der Compiler war das einzige Problem" übergangen war - es gab legitime mikroarchitektonische Probleme, die I2 wirklich keinen Gefallen für Allzweck-Code bedeuteten -, machte es keinen besonderen Spaß, Code für den Vergleich zu generieren zu den engeren, höher getakteten OoO-Maschinen des Tages. Wenn man es richtig füllen konnte, was oft mit PGO oder Handcodierung verbunden war, war es großartig - aber die meiste Zeit war die Leistung von Compilern wirklich nur wenig anregend. IPF hat es nicht einfach gemacht, großartigen Code zu generieren, und es war unversöhnlich, wenn Code nicht großartig war.
quelle
Was Sie beschreiben, ist ein bisschen, was Transmeta mit ihrer Code-Morphing-Software versucht hat (die x86-Bytecode dynamisch in Transmeta-internen Maschinencode übersetzt hat).
Warum hat Intel nicht gut genug für IA64 kompiliert? Ich vermute, sie hatten nicht genug Compiler-Know-how im Haus (auch wenn sie natürlich einige sehr gute Compiler-Experten im Haus hatten, aber wahrscheinlich nicht genug für IA64) machen eine kritische Masse). Ich vermute, dass ihr Management den Aufwand für die Erstellung eines Compilers unterschätzt hat.
AFAIK, Intel EPIC ist gescheitert, weil die Kompilierung für EPIC sehr schwierig ist, und auch, weil andere Wettbewerber, wenn sich die Compilertechnologie langsam und allmählich verbessert, ebenfalls in der Lage waren, ihren Compiler (z. B. für AMD64) zu verbessern und etwas Compiler-Know-how auszutauschen.
Übrigens wünschte ich mir, AMD64 wäre ein weiterer RISCy-Befehlssatz. Es könnte ein POWERPC64 gewesen sein (aber es war wahrscheinlich nicht wegen Patentproblemen, wegen der damaligen Microsoft-Anforderungen, etc ...). Die x86-64-Befehlssatzarchitektur ist wirklich keine "sehr gute" Architektur für Compiler-Writer (aber irgendwie "gut genug").
Auch die IA64-Architektur hat einige starke Einschränkungen mit sich gebracht, z. B. waren die 3 Befehle / Wort gut, solange der Prozessor 3 Funktionseinheiten zur Verarbeitung hatte, aber nachdem Intel auf neuere IA64-Chips umgestiegen war, fügten sie weitere Funktionseinheiten hinzu. Level-Parallelität war erneut schwer zu erreichen.
Vielleicht wird RISC-V (ein Open-Source-ISA) nach und nach so erfolgreich sein, dass es mit anderen Prozessoren konkurriert.
quelle
Wie Robert Munn betonte, war es die mangelnde Abwärtskompatibilität, die das Itanium (und viele andere "neue" Technologien) tötete.
Möglicherweise war es schwierig, einen neuen Compiler zu schreiben, aber Sie benötigen nur einige davon. Ein AC-Compiler, der optimierten Code erzeugt, ist ein Muss - sonst haben Sie kein brauchbares Betriebssystem. Sie benötigen einen C ++ - Compiler, Java, und vorausgesetzt, die Hauptbenutzerbasis wäre Windows, eine Art Visual Basic. Das war also kein wirkliches Problem. Es gab ein anständiges Betriebssystem (NT) und einen guten C-Compiler.
Was für ein Unternehmen, das ein Softwareprodukt anbietet, als trivialer Aufwand erscheint: Kompilieren Sie Ihre C-Codebasis neu und testen Sie sie erneut (und zu diesem Zeitpunkt wären die meisten in reinem C geschrieben worden!), War nicht so einfach. Das Konvertieren einer großen Menge von C-Programmen, die eine 32-Bit-Ganzzahl und eine 32-Bit-Adressierung voraussetzten, in eine native 64-Bit-Architektur war voller Fallstricke. Wäre IA64 zu einem dominanten Chip geworden (oder sogar zu einem beliebten!), Hätten die meisten Softwareunternehmen die Kugel gebissen und sich die Mühe gemacht.
So ein schneller Chip mit einem vernünftigen Betriebssystem, aber einem sehr begrenzten Satz verfügbarer Software, deshalb haben nicht viele Leute ihn gekauft, deshalb haben nicht viele Softwarefirmen Produkte dafür bereitgestellt.
quelle
Was Itanium tötete, waren Verzögerungen bei der Auslieferung, die es AMD64 ermöglichten, einzugreifen, bevor sich die Softwareanbieter zur Migration auf IA64 für 64-Bit-Apps verpflichteten.
Es war eine gute Idee, die Optimierung dem Compiler zu überlassen. Eine Menge Dinge können statisch erledigt werden, die sonst in der Hardware ineffizient sind. Die Compiler waren ziemlich gut darin, besonders wenn sie PGO-Profiling verwendeten (ich arbeitete bei HP und der Compiler von HP übertraf in der Regel Intels). PGO war ein harter Verkauf, es ist jedoch ein schwieriger Prozess für den Produktionscode.
IPF sollte abwärtskompatibel sein, aber als AMD64 gestartet wurde, ging der Kampf verloren und ich glaube, die X86-Hardware in der CPU wurde nur entfernt, um als Server-CPU neu auszurichten. Itanium als Architektur war nicht schlecht, die 3 Anweisungen pro Wort waren kein Problem. Was ein Problem war, ist die Hyper-Threading-Implementierung durch Stapeltausch während der Speicher-E / A-Phase, die zu langsam war (um die Pipeline zu leeren und neu zu laden), bis Montecito usw., was verhinderte, dass sie mit PowerPC-CPUs außer Betrieb konkurrierte. Die Compiler mussten verspätete Fehler bei der CPU-Implementierung beheben, und ein Teil des Leistungsvorteils war zu gering, um Fehler vorherzusagen.
Die Architektur ermöglichte es Itanium, relativ einfach zu sein, während dem Compiler Tools zur Verfügung gestellt wurden, mit denen er die Leistung optimieren konnte. Wenn die Plattform gewohnt hätte, wären die CPUs komplexer geworden und würden schließlich zu Threads, Betriebsstörungen usw. wie x86. Die ersten Gens konzentrierten sich jedoch auf andere Leistungsschemata, da der Compiler einen Großteil des harten Materials handhabte.
Die IPF-Plattform setzte auf den Compiler und die Tools, und es war die erste Architektur, die ein äußerst vollständiges und leistungsstarkes PMU-Design (Performance Monitoring Unit) enthüllte, das später auf Intel x86 portiert wurde. Leistungsstarke Tool-Entwickler nutzen es immer noch nicht vollständig, um Code zu profilieren.
Wenn man sich die Erfolge von ISA ansieht, ist es oft nicht die technische Seite, die den Ausschlag gibt. Es ist sein Platz in der Zeit und den Kräften des Marktes. Schauen Sie sich SGI Mips, DEC Alpha an ... Itanium wurde nur von den Verlierern, SGI- und HP-Servern, Unternehmen mit Management, die sich auf strategische Geschäftsfehler stauten, unterstützt. Microsoft war nie voll dabei und befürwortete AMD64, sich nicht nur mit Intel als Spieler einzulassen, und Intel spielte nicht richtig mit AMD, um ihnen die Möglichkeit zu geben, im Ökosystem zu leben, da sie beabsichtigten, AMD zu schnupfen.
Wenn Sie sich ansehen, wo wir heute sind, hat die komplexe Hardware von X86 bisher zu einer Sackgasse geführt. Wir stecken bei 3 + GHz fest und werfen Kerne ab, für die nicht genug Verwendung vorhanden ist. Das einfachere Design von Itanium hätte mehr Material auf den Compiler geschoben (Raum für Wachstum), wodurch dünnere, schnellere Pipelines erstellt werden könnten. Bei der gleichen Generation und Fab-Technologie wäre es zwar schneller gelaufen und hätte die Obergrenze erreicht, aber ein bisschen höher, und möglicherweise mussten andere Türen geöffnet werden, um Moores Gesetz durchzusetzen.
Naja zumindest ist das oben meine Überzeugung :)
quelle
Der Speicher wird vage ... Itanium hatte einige großartige Ideen, die großartige Compiler-Unterstützung benötigen würden. Das Problem war, dass es sich nicht um eine Funktion handelte, sondern um viele. Jeder war keine große Sache, alle zusammen waren es.
Beispielsweise gab es eine Schleifenfunktion, bei der eine Iteration der Schleife Register aus verschiedenen Iterationen bearbeitet. x86 behebt das gleiche Problem durch die Möglichkeit einer massiven Störung.
Zu dieser Zeit waren Java und JVMs in Mode. Was IBM sagte, war, dass Sie mit PowerPC Bytecode schnell kompilieren konnten und die CPU es schnell machen würde. Nicht auf Itanium.
quelle