Ich hab jetzt noch nicht alle Reaktionen zu dem Artikel gelesen, aber je mehr ich drüber nachdenke, desto mehr scheint mir eine Sache auffällig:
Ist die Grundprämisse des Artikels nicht grundlegend falsch?
Möglicherweise, ist aber auch eigentlich irrelevant, wenn sich aus x86 ISA-Bedingt nicht mehr Performance pro Thread holen lässt ist das eben ein inhärenter Nachteil davon, oder anders gesehen ein Performance Vorteil für ARM.
Ob man mit SMT mehr Performance herausholen kann ist bei der Betrachtung der Single-Thread-Performance irrelevant, weil ohne angepasste Software bringt SMT in jedem fall nix, und von mehr Durchsatz pro Thread profitiert jede Software und ist damit in jedem Fall vorteilhafter.
Genauso gut könnte ich sagen, die ganze Welt hat Bulldozer falsch getestet, die erbärmliche Single-Thread Performance ist ja nicht die Wahrheit, weil Bulldozer wurde ja "designed for multithreading".
Oder ich kann den ganzen Spieß umdrehen, und sagen die ganzen Multithread-Tests sind falsch, weil ARM könnte ja im selben Powerbudget wahrscheinlich 2-4x mehr Kerne unterbringen, also sind ja die ganzen Test M1 4-Kerner gegen Renoir 8-Kerner+SMT falsch (und der M1 ist selbst in dieser Situation zumindest mit nativem Code meistens schneller)
Ich spreche von der Aussage des zitierten "architects":
Mir ist absolut nicht klar, warum SMT für x86/CISC prinzipbedingt einen größeren vorteil im Vgl. zu RISC-Architekturen bieten soll.
Da muss man sehr weit in die Geschichte der Rechnerarchitektur zurückgehen, so weit dass es unsicher ist wie viel heute davon noch auf die Architekturen der Micro und Macro-Ops zutrifft.
Man muss verstehen wie und warum sich die Paradigmen der CISC und RISC Architekturen entwickelt haben.
CISC wurde zu einem Zeitpunkt entwickelt, als es noch üblich war Programme in Assembler zu coden. Ein wesentlicher Punkt für diese Entwicklung war es den Entwicklern die Arbeit zu erleichtern. Auch wenn das "Complex" in CISC erstmal danach klingt als wäre es schwieriger zu erlernen, ist ein mächtigerer Befehlssatz für die Softwareentwicklung wesentlich einfacher, da man mit weniger Befehlen das selbe Problem lösen kann.
Das kann man an folgendem Beispiel auch recht gut sehen:
Stell dir eine einfache RISC-ISA vor die keinen nativen Befehl für die Multiplikation hat. Das ist auch nicht notwendig, da eine Multiplikation immer durch eine mehrfache Addition simuliert werden kann. Wenn tatsächlich in Assembler programmiert wird, müsste der Entwickler für jede einzelne Multiplikation eine Schleife bauen, welche diese mehrfache Addition vornimmt, wobei Schleife eigentlich falsch ist, das ist schon ein Hochsprachenkonstrukt, in Hardware gibt es keine Schleifen, nur bedingte und unbedingte Sprünge, was das ganze noch mal wesentlich komplizierter macht.
Auf einer CISC Architektur die eine native Multiplikation kennt bräuchte man dagegen nur 1 Zeile.
CISC wurde also in erster Linie dafür entwickelt für den Menschen gut lesbar zu sein, nicht um für Maschinen gut lesbar zu sein.
Wobei CISC in der damaligen Zeit auch für die Hardware Vorteile hatte. Unter anderem war Speicher extrem teuer, und weniger Befehle heißt auch, dass CISC Programme weniger Speicher benötigen, also es war es auch ein wirtschaftlicher Vorteil.
Mit der Zeit wurden die Befehlssätze aber immer komplexer und es war mit CISC nicht mehr möglich alle Befehle nativ auszuführen. Also gab es Mikroprogramme direkt in den CPUs integriert, welche die komplexen Befehle auseinandernahmen und erst zur Laufzeit den eigentlich auszuführenden Code erzeugten.
Um zu dem vorherigen Beispiel zurückzukommen: Es ist nicht unbedingt notwendig dass, die fiktive CISC-Maschine auch tatsächlich eine ALU hat die multiplizieren kann um den Befehl in der ISA zur Verfügung zu stellen. Genauso gut könnte in der CPU ein Mikroprogramm laufen, welches aus dem Multiplikationsbefehl die notwendige Schleife erzeugt um die Multiplikation mittels Addition zu lösen.
Die Komplexität der Befehlssätze wurde also immer größer und damit auch die Komplexität der notwendigen Mikroprogramme. Letzteres wurde mit der Zeit immer problematischer, da jene in einem ROM direkt in der CPU liegen, und damit bei Fehlern nicht einfach ausgetauscht werden können.
Die Folge war, dass man die Befehlssätze wieder aufs nötigste reduzierte, Compiler waren mittlerweile fortgeschritten genug, dass man nicht mehr in Assembler programmieren musste, und die RISC-Idee war geboren.
Mit den RISC Befehlssätzen hat sich etwas sehr wesentliches geändert, die Befehlslänge war nun konstant.
Das führte dazu, dass die Idee des Pipelining realisiert werden konnte. Durch die konstante Befehlslänge musste der Programm-Counter immer garantiert um einen fixen Wert (oder ein vielfaches davon) inkrementiert/dekrementiert werden, und das wichtigste ist, dieser Wert ist immer bekannt. Mit variabler Befehlslänge weiß man erst nach dem Decoding wo der nächste Befehl beginnt.
Gleichzeitig vereinfacht es die Hardware enorm um Befehle in mehrere kleine Teile zu zerlegen die parallel abgearbeitet werden können.
Jenes Pipelining war es, dass damaligen RISC Prozessoren enorme Performancevorteile verschafft hat, bis dahin waren es nicht Instructions per Cycle sondern Cycles per Instruction.
Durch das Pipelining war erstmals ein Durchsatz von 1 Befehl pro Takt möglich.
Von diesen brauchte man mit RISC zwar mehr, aber wenn CISC für jeden Befehl gleich mehrere Takte braucht war man natürlich trotzdem schneller.
Die nächste Beschleunigung war dann OOOE, die ebenfalls durch RISC deutlich vereinfacht wurde.
Die Einfachheit der Befehle hatte auch zur Folge, dass jeder Befehl gleich viele Takte in der Pipeline braucht, was damit den Aufbau einer OOO Architektur wesentlich erleichterte.
Bis, nun ja bis Intel mit dem Pentium Pro das komplexe Decoding von x86 von der eigentlichen Ausführung entkoppelt hat und damit auch die Speedups durch OOE und Pipelining mitnehmen konnte.
Es ist also durchaus denkbar, dass es auch heute noch mit einem RISC Befehlssatz viel mehr ILP extrahieren lässt, als es mit x86 möglich wäre.
Ein weiterer Punkt sind die Decoder. Apple hat hier ein viel breiteres Design, was auch bedeutet dass es viel einfacher ist das Backend auch mit 1 Thread gut auszulasten.
Mit ziemlicher Sicherheit würde Apple also SMT wesentlich weniger bringen als bei x86, was jetzt aber keine Schwäche von deren SMT Umsetzung, sondern eine Stärke wäre, weil eben viel weniger Ressourcen brach liegen.
Die Frage ist nun ob x86 das Frontend auch so stark verbreitern könnte um bei der Performance pro Thread gleichzuziehen.
Ich würde dazu sagen eher unwahrscheinlich. Soweit ich weiß arbeiten die Decoder in modernen x86 Prozessoren quasi nach dem Trial&Error Prinzip, heißt sie machen sehr viel Arbeit umsonst, und verschwenden damit eine Menge Energie. Da bei x86 eben die Befehlslänge nicht im vorhinein bekannt ist, laden die Decoder einen Datenstrom aus dem I-Cache und probieren erstmal alle möglichen Instruktionslängen durch bis sie die richtige gefunden kann. Erst dann ist bekannt wo die Grenze zwischen 2 Befehlen ist.
Die Decoder noch breiter zu machen dürfte die Energieverschwendung wohl noch weiter erhöhen, falls nicht jemand eine geniale Idee hat wie man das Ganze anders lösen könnte.