3 Punkte von GN⁺ 2024-07-29 | 1 Kommentare | Auf WhatsApp teilen
  • SMT ist eine Technik, bei der ein CPU-Kern im selben Taktzyklus Befehle aus mehreren Threads ausgibt, um Ausführungseinheiten besser auszulasten, die allein durch Parallelität auf Befehlsebene ungenutzt blieben.
  • Intels Hyper-Threading implementiert zwei Threads pro Kern und dupliziert den Architekturzustand, sodass dem Betriebssystem ein physischer Kern wie zwei logische Prozessoren erscheint.
  • In der tatsächlichen Implementierung werden nicht einfach alle Ressourcen verdoppelt: Instruction Pointer, ITLB und RAT werden dupliziert, Trace Cache und TLB werden geteilt, während uop queue, physische Register und reorder buffer gleichmäßig aufgeteilt werden.
  • Der Leistungsgewinn hängt von der Workload ab: Wenn zwei Threads um den Cache konkurrieren, kann es langsamer werden; kooperierende Threads, die Daten austauschen, können dank gemeinsam genutztem Cache schneller werden.
  • Gemeinsam genutzte Ressourcen und spekulative Ausführung können zu Sicherheitslücken führen; in sicherheitskritischen Umgebungen oder bei Workloads, die maximale Performance und minimale Latenz benötigen, ist SMT zu deaktivieren eine realistische Option.

Warum SMT nötig ist

  • Moderne Prozessoren verfügen über Hunderte von Registern, mehrere Load/Store-Einheiten und arithmetische Einheiten und nutzen Techniken der Parallelität auf Befehlsebene wie Pipelining, superskalare Architekturen und Out-of-Order-Ausführung, um diese auszulasten.
  • Eine Pipeline teilt die Befehlsausführung in mehrere Stufen auf und reicht in jedem Taktzyklus Befehle an die nächste Stufe weiter; bei einer Pipeline-Tiefe von 5 können ab dem fünften Zyklus bis zu 5 Befehle gleichzeitig in Bearbeitung sein.
  • Superskalare Prozessoren können in einem Taktzyklus mehrere Befehle ausgeben; aktuelle Intel-Core-i7-Prozessoren können 4 Befehle pro Zyklus ausgeben.
  • In echten Programmen ist es schwierig, genügend unabhängige Befehle zu finden, sodass Ausführungseinheiten zeitweise ungenutzt bleiben.
    • Horizontale Verschwendung entsteht, wenn innerhalb eines Threads nicht genügend unabhängige Befehle gefunden werden, um die issue width zu füllen.
    • Vertikale Verschwendung entsteht, wenn die nächsten Befehle vom aktuell ausgeführten Befehl abhängen und in einem Taktzyklus gar kein Befehl ausgegeben werden kann.
  • Traditionelles Multithreading kann vertikale Verschwendung reduzieren, indem pro Taktzyklus nur Befehle eines Threads ausgegeben werden und im nächsten Zyklus auf einen anderen Thread gewechselt wird; horizontale Verschwendung und der Overhead des Kontextwechsels bleiben jedoch bestehen.
  • SMT gibt ohne Kontextwechsel im selben Taktzyklus Befehle aus mehreren Threads aus und füllt die Ausführungseinheiten dadurch zu einem höheren Anteil.
  • Intels SMT-Implementierung Hyper-Threading ist auf zwei Threads pro Kern beschränkt.

Grundstruktur von SMT nach Intel-Art

  • Ein gewöhnlicher Nicht-SMT-Prozessor kann jeweils nur Befehle eines Threads ausführen.
  • Jeder Thread besitzt einen Architekturzustand, der Registerwerte, Programmzähler, Steuerregister usw. umfasst.
  • Um Befehle aus zwei Threads gleichzeitig auszuführen, müssen die Zustände beider Threads gleichzeitig repräsentiert werden; SMT-Implementierungen duplizieren daher den Architekturzustand des Prozessors.
  • Durch diese Duplizierung erscheint ein physischer Prozessor dem Betriebssystem als zwei logische Prozessoren, und das Betriebssystem kann auf beiden Threads schedulen.
  • Puffer und Ausführungsressourcen auf Mikroarchitekturebene werden je nach Faktoren wie Kosten, Leistungsaufnahme und Chipfläche dupliziert, geteilt oder partitioniert.
  • Im Mittelpunkt steht hier vor allem Intels SMT-Implementierung, basierend auf Intels Whitepaper von 2002.

Die drei Teile der CPU-Mikroarchitektur

  • Ein Prozessor stellt Programmierern die ISA als öffentliche Schnittstelle bereit; die ISA umfasst den Befehlssatz und die Register, die Befehle verwenden können.
  • Die Mikroarchitektur ist die interne Implementierung, die sich auch zwischen Prozessormodellen unterscheiden kann, die dieselbe ISA unterstützen.
  • Die Mikroarchitektur moderner Prozessoren lässt sich grob in drei Teile gliedern:
    • Frontend: Enthält die Befehlssteuereinheit, die die als Nächstes auszuführenden Programmbefehle holt und dekodiert.
    • Backend: Enthält Ausführungsressourcen wie physische Register, arithmetische Einheiten und Load/Store-Einheiten und weist dekodierten Befehlen Ressourcen zu, um ihre Ausführung zu planen.
    • retirement unit: Übernimmt die Ergebnisse ausgeführter Befehle endgültig in den Architekturzustand des Prozessors.

SMT im Frontend

  • Der Instruction Pointer verfolgt die Adresse des nächsten zu holenden Befehls.
    • SMT-fähige Prozessoren besitzen zwei Sätze von Instruction Pointern, um die nächsten Befehle zweier Programme unabhängig zu verfolgen.
  • Der Trace Cache speichert kürzlich dekodierte Befehls-Traces, um die Dekodierkosten und Ausführungslatenz wiederholt ausgeführter Befehle zu reduzieren.
    • Er wird von zwei logischen Prozessoren je nach Bedarf dynamisch gemeinsam genutzt.
    • Wenn ein Thread mehr Befehle ausführt, kann er mehr Einträge im Trace Cache belegen.
    • Jeder Eintrag wird mit Thread-Informationen markiert, um Befehle der beiden Threads zu unterscheiden.
    • Der Zugriff auf den Trace Cache wird in jedem Zyklus zwischen den beiden logischen Prozessoren arbitriert.
  • Bei einem Trace-Cache-Miss sucht das Frontend im L1 Instruction Cache nach dem Befehl an der betreffenden Adresse; bei einem L1-Instruction-Cache-Miss muss er aus der nächsten Cache-Ebene oder dem Hauptspeicher geholt werden.
  • Der L1 Instruction Cache cached Daten anhand virtueller Adressen, für den Zugriff auf den Hauptspeicher werden jedoch physische Adressen benötigt.
  • Die ITLB enthält kürzlich übersetzte virtuelle Adressen und übersetzt virtuelle in physische Adressen.
    • In SMT-fähigen Prozessoren besitzt jeder logische Prozessor seinen eigenen ITLB-Cache.
    • Die Logik zum Holen von Befehlen aus dem Hauptspeicher arbeitet nach dem First-come-first-served-Prinzip, reserviert aber mindestens einen Request-Slot pro logischem Prozessor, damit beide logischen Prozessoren vorankommen können.
    • Aus dem Hauptspeicher eintreffende Befehle werden vor dem Dekodieren in einem kleinen Streaming Buffer gespeichert; in SMT-fähigen Prozessoren wird auch dieser Puffer pro logischem Prozessor dupliziert.
  • Nach dem Holen werden Befehle in kleinere, einfachere uops dekodiert.
    • uops gelangen in die uop queue, die als Grenze zwischen CPU-Frontend und -Backend dient.
    • Die uop queue wird gleichmäßig zwischen den beiden logischen Prozessoren geteilt; diese statische Partitionierung ermöglicht den beiden logischen Prozessoren unabhängigen Fortschritt.

SMT im Backend

  • Das Backend holt Mikrobefehle aus der uop queue und führt sie aus, ist dabei aber nicht ausschließlich an die ursprüngliche Programmreihenfolge gebunden, sondern nutzt Out-of-Order-Ausführung.
  • Nahe beieinanderliegende Programmbefehle hängen häufig voneinander ab; gibt es eine Operation mit langer Latenz wie einen Hauptspeicherzugriff, müssen auch abhängige Befehle warten.
  • Die Out-of-Order-Engine führt weiter hinten liegende Befehle vor ihrer ursprünglichen Reihenfolge aus und reduziert so Ressourcenverschwendung.
  • Der allocator identifiziert die für Mikrobefehle benötigten Ressourcen und weist sie je nach Verfügbarkeit zu.
    • In einem Zyklus weist er Ressourcen für Mikrobefehle eines logischen Prozessors zu und wechselt im nächsten Zyklus zum anderen logischen Prozessor.
    • Wenn in der uop queue nur Mikrobefehle eines logischen Prozessors liegen oder ein logischer Prozessor seinen Ressourcenanteil vollständig ausgeschöpft hat, nutzt der allocator alle Zyklen für den anderen logischen Prozessor.
  • Die wichtigsten Ressourcen im Backend sind teils dupliziert, teils gemeinsam genutzt, teils partitioniert.
    • Auf ISA-Ebene besitzt X86-64 nur 16 allgemeine Integer-Register, auf Mikroarchitekturebene gibt es jedoch Hunderte physischer Integer-Register und eine ähnliche Zahl von Gleitkommaregistern.
    • In SMT-fähigen Prozessoren werden physische Register gleichmäßig auf die beiden logischen Prozessoren aufgeteilt.
    • Auch load buffer und store buffer für Speicherlese- und Schreiboperationen werden gleichmäßig auf die beiden logischen Prozessoren aufgeteilt.

Register-Renaming, Scheduling und Commit

  • Für Out-of-Order-Ausführung führt das Backend Register-Renaming durch.
    • Da es auf ISA-Ebene nur wenige Architekturregister gibt, verwenden Programmbefehle dieselben Register in mehreren unabhängigen Befehlen wieder.
    • Die Out-of-Order-Engine ersetzt das ursprüngliche logische Register durch eines der physischen Register und ermöglicht so frühere sowie parallele Ausführung.
    • Diese Zuordnung wird in der register alias table, kurz RAT, verwaltet.
    • Da die beiden logischen Prozessoren jeweils eigene Sätze von Architekturregistern besitzen, haben sie auch jeweils eine eigene Kopie der RAT.
  • Befehle, die Register-Renaming und allocator-Stufen durchlaufen haben, gelangen in Bereitschaftswarteschlangen.
    • Eine Queue ist für Speicherlese- und Schreibbefehle vorgesehen, die andere für allgemeine Befehle.
    • In SMT-fähigen Kernen werden diese Queues gleichmäßig auf die beiden logischen Prozessoren aufgeteilt.
  • Der Prozessor besitzt mehrere instruction scheduler, die parallel arbeiten.
    • In jedem CPU-Zyklus wird ein Teil der Befehle aus den Bereitschaftsqueues an Scheduler weitergegeben.
    • Die Queue sendet in einem Zyklus Befehle eines logischen Prozessors und wechselt im nächsten Zyklus zum anderen logischen Prozessor.
    • Der Scheduler kümmert sich nicht um den logischen Prozessor, sondern schickt Mikrobefehle, deren benötigte Operanden und Ausführungseinheiten bereit sind, sofort zur Ausführung.
    • Aus Fairness-Gründen ist die Zahl der active entries begrenzt, die ein logischer Prozessor innerhalb der scheduler queue besitzen darf.
  • Die Ergebnisse fertig ausgeführter Befehle gelangen in den reorder buffer.
    • Auch wenn Befehle out of order ausgeführt werden, müssen sie in der ursprünglichen Programmreihenfolge in den Architekturzustand des Prozessors übernommen werden.
    • In SMT-fähigen Kernen wird der reorder buffer gleichmäßig auf die beiden logischen Prozessoren aufgeteilt.
  • Die retirement unit verfolgt, ob Befehle bereit sind, in den Architekturzustand übernommen zu werden, und retired sie in der korrekten Programmreihenfolge.
    • In SMT-fähigen Kernen verarbeitet sie abwechselnd Mikrobefehle der einzelnen logischen Prozessoren.
    • Wenn ein logischer Prozessor keine Mikrobefehle zum Retiren hat, wird die gesamte Bandbreite für den anderen logischen Prozessor genutzt.
    • Nach dem Retiren eines Befehls muss unter Umständen in den L1 Cache geschrieben werden; auch diese Schreibauswahl-Logik wechselt in jedem Zyklus zwischen den beiden logischen Prozessoren.

Speichersubsystem und Cache-Effekte

  • Der TLB, der virtuelle Adressen von Datenanforderungen in physische Adressen übersetzt, wird von den beiden logischen Prozessoren je nach Bedarf dynamisch gemeinsam genutzt.
  • TLB-Einträge werden mit einer logical processor id markiert, um Einträge der beiden logischen Prozessoren zu unterscheiden.
  • Jeder CPU-Kern besitzt seinen eigenen privaten L1 Cache.
  • Der L2 Cache kann je nach Mikroarchitektur privat sein oder zwischen Kernen geteilt werden.
  • Falls ein L3 Cache vorhanden ist, wird er zwischen Kernen geteilt.
  • Caches sind sich der Existenz logischer Prozessoren nicht bewusst.
  • Da der L1 Cache und je nach Fall auch der L2 Cache kernprivat sind, enthalten sie bei Bedarf Daten beider logischer Prozessoren gemeinsam.
    • Wenn zwei Threads den Cache aggressiv nutzen, können Datenkonflikte und Evictions auftreten und die Performance sinken.
    • Wenn zwei Threads mit demselben Datensatz arbeiten, kann der gemeinsam genutzte Cache die Performance erhöhen.

Entscheidungskriterien bei Performance und Sicherheit

  • Selbst wenn auf einem SMT-fähigen Kern nur ein Thread läuft, bleiben viele Puffer und Ausführungsressourcen zwischen den beiden logischen Prozessoren geteilt oder partitioniert, was die potenzielle Single-Thread-Performance verringern kann.
  • Auf dem nicht genutzten logischen Prozessor führt das Betriebssystem eine idle loop aus; auch diese Schleife kann Ressourcen verbrauchen, die der andere logische Prozessor für maximale Performance nutzen könnte.
  • Bei Intel-Core-Prozessoren scheint es keine Ressourcenteilung oder -partitionierung zu geben, wenn auf einem Kern nur ein Thread läuft; Intel behandelt dies als Verbesserung, die in dieser Generation eingeführt wurde.
  • Wenn zwei Threads auf den beiden logischen Prozessoren eines SMT-fähigen Kerns laufen, bestimmt das Cache-Zugriffsmuster die Performance.
    • Wenn zwei Threads um den Cache konkurrieren, evicten sie gegenseitig ihre Daten und die Performance sinkt.
    • Wenn sie kooperieren, etwa indem ein Thread Daten produziert, die der andere konsumiert, kann die gemeinsame Nutzung von Cachedaten die Performance verbessern.
    • Wenn zwei Threads den Cache nicht konkurrierend nutzen, können sie die Auslastung der CPU-Kernressourcen erhöhen, ohne die Performance des jeweils anderen zu beeinträchtigen.
  • Viele Fachleute sind der Ansicht, dass Programme, die absolute Maximalleistung benötigen, SMT besser deaktivieren sollten, damit ein einzelner Thread alle Ressourcen nutzen kann.
  • SMT bringt auch Sicherheitsprobleme mit sich.
    • Gemeinsam genutzte Ressourcen und spekulative Ausführung können die Möglichkeit eröffnen, dass sensible Daten an Angreifer durchsickern.
    • Dokumente von Oracle Linux und Red Hat werden als Beispiele für SMT-bezogene Sicherheitsprobleme verlinkt.
    • Die allgemeine Empfehlung geht dahin, SMT auf dem System zu deaktivieren.
    • Es gibt auch Gerüchte, dass Intel Hyper-Threading in der nächsten Prozessorgeneration Arrow Lake entfernen könnte.

Referenzen

1 Kommentare

 
GN⁺ 2024-07-29
Meinungen auf Hacker News
  • Wenn man SMT stark vereinfacht versteht, leuchtet ein, dass es die wertvollen ALUs weiter beschäftigen kann, während ein Thread wegen eines Cache Miss angehalten ist.
    LPDDR in älteren Laptops war langsamer und es gab weniger Kerne, daher dürfte der Nutzen damals größer gewesen sein; heute hat man aber oft mehr Kerne als skalierbare Arbeit, sodass der Wert weniger spürbar ist.
    Man vermeidet auch Cache-Konkurrenz, indem man Aufgaben nicht auf denselben Kern wie einen wichtigen Thread legt, weil man weiß, dass die Single-Thread-Leistung der Flaschenhals ist.
    Früher habe ich beim Multithread-Rendering von DirectX 12 Efficient-/Performance-Cores und SMT-Cores getestet: Auf einem i7-12700K waren die Renderzeiten komplexer Szenen mit nur P-Cores, P+SMT sowie P+E+SMT fast gleich. Auf der Xbox Series X war derselbe Test jedoch etwas schneller, wenn auch SMT mit Arbeit belegt wurde.

    • Rendering war von Anfang an eines der Szenarien, in denen SMT gleich schnell oder langsamer war. Es gibt ohnehin viele mathematische Operationen, sodass die FPU ständig ausgelastet ist, insbesondere weil der Dividierer die teuerste Operation im Prozessor ist.
      SMT glänzt, wenn auf Ein-/Ausgabe gewartet wird oder einfache Integer-Arbeit anfällt. Wenn beide Threads die FPU auslasten können, wird SMT meist langsamer, weil zusätzliches Tagging nötig ist, um interne CPU-Daten zuzuordnen.
    • Intels Hyper-Threading ist im Grunde eher ein Hack der Write-Pipeline.
      Der Kernpunkt sind weniger Cache Misses, sondern dass der Core andere Dinge ausführen kann, während Schreibvorgänge abgeschlossen werden.
      Deshalb skaliert mancher Code schlecht, während anderer Code nahezu lineare Geschwindigkeitsgewinne erzielt.
    • Heutzutage frage ich mich, besonders mit Blick auf rückseitige Stromversorgung, wie stark ein Cache-Stall eines Prozessors das thermische Throttling dieses Prozessors und seiner Nachbarn reduziert.
      Vielleicht ist es einfach besser, solche Prozessoren zwischendurch kurz ein Nickerchen machen zu lassen.
    • Zum Punkt, dass LPDDR früher langsamer war: Merkwürdigerweise hat sich die Latenz kaum verbessert. Die CAS-Latenz von DDR2/3/4/5 liegt meist im Bereich von 5 bis 10 ns.
      Busbreite, Transfers pro Sekunde, Queuing und die Energie pro übertragenem bzw. gespeichertem Bit wurden verbessert, aber wenn ein Programm Daten braucht, die nicht im Cache liegen, und auch die Vorhersage danebenliegt, ist am Ende die RAM-Latenz das Problem.
    • Ich frage mich, ob man statt SMT ungenutzte ALUs/FPUs kurz abschalten könnte, während die Frontend-Pipeline auf etwas wartet, und so eher Wärmeentwicklung und Stromverbrauch senkt, statt die Auslastung zu maximieren.
  • Intels nächste Arrow-Lake-CPUs sollen Hyper-Threading, also SMT, vollständig entfernen.
    Da der Leistungsgewinn schon immer stark von der Anwendung abhing, könnte Vereinfachung besser sein.
    Eine aktuelle Diskussion dazu, wann und wo es sinnvoll ist, gibt es hier: https://news.ycombinator.com/item?id=39097124

    • Die meisten Programme stoßen irgendwann an eine Grenze, wie viele Threads sie sinnvoll nutzen können. Wenn es deutlich weniger Kerne als diese Grenze gibt, ist SMT sinnvoll, um CPU-Ressourcen besser zu nutzen; sobald aber genügend Kerne vorhanden sind, ergibt SMT möglicherweise keinen Sinn mehr.
      Ich bin noch nicht sicher, dass wir diesen Punkt schon erreicht haben, aber Intels P-/E-Cores sind eine Alternative mit ähnlichem Ziel und wirken auf Desktops mit vielen Single- und Low-Thread-Workloads ziemlich plausibel. Es scheint auch wertvoll zu sein, bei der Anwendungsoptimierung nicht zwischen SMT und E-Cores unterscheiden zu müssen.
      AMD hingegen will vorerst weitgehend homogene Kerne beibehalten und SMT weiter nutzen. Welche Strategie tatsächlich besser ist, dürfte je nach Anwendung stark variieren und schwer pauschal zu beurteilen sein.
    • In meinem persönlichen Anwendungsfall, bei dem ich Spiele und Engines entwickle, war es schneller, zum Gott der CPU-Thread-Platzierung zu beten, dass jeder Thread seinen eigenen Kern bekommt, als Hyper-Threading zu verwenden.
      Deshalb habe ich beschlossen, die Thread-Zahl auf std::thread::hardware_concurrency() / 2 - 1, also Anzahl der Kerne - 1, zu begrenzen. Ich arbeite mit std::vector.
    • Nach branchenüblichen Benchmarks war Intel Hyper-Threading mindestens in jeder zweiten Generation langsamer, als es abzuschalten.
      Selbst wenn es gut funktionierte, lag der Zugewinn nur im niedrigen zweistelligen Prozentbereich, und es gab aufeinanderfolgende Generationen, in denen es schlechter war; ich weiß nicht, warum man es weiter versucht.
    • Gilt das auch für Server-Teile?
  • Ich bin jedes Mal erstaunt, wenn ich lese, wie solche Low-Level-CPU-Funktionen arbeiten.
    An der Uni habe ich eine Vorlesung gehört, die etwa „Einführung in Computerhardware“ hieß, tatsächlich aber „Einführung in CPU-Design“ hätte heißen sollen. Wir bauten aus Logikgattern Addierer, Latches, Flipflops und Ähnliches, und am Ende des Semesters konnten wir auf Gatterebene einen sehr einfachen Prozessor entwerfen.
    Aber sich Dinge wie Register Renaming oder Out-of-Order Execution auszudenken, kann ich mir kaum vorstellen. Entwirft man so etwas auch auf Gatterebene? Oder gibt es eine Sprache dafür und eine Art „Compiler“, der Gatter und Transistoren platziert?

    • Ich habe den Folgekurs belegt und dabei SMT sowie ein paar weitere Dinge gelernt.
      Alle Aufgaben haben wir in einer Hardwarebeschreibungssprache namens Verilog gemacht, wodurch man mehrere Elemente abstrahiert beschreiben konnte.
  • Ein großes Missverständnis, das Nutzer bei SMT häufig haben, ist das mentale Modell, es gebe einen „echten Core“ und daneben einen minderwertigen Core.
    In allen beobachtbaren Aspekten sind die beiden Threads gleichwertig.

    • Diese Wahrnehmung scheint aus der Performance zu kommen. Beide Threads können zwar dieselbe Arbeit ausführen, aber es ergibt sich nicht die doppelte Leistung wie bei einem „echten“ zweiten Thread, also einem zweiten Core.
      Wenn man nur auf die Leistung schaut, entspricht es konzeptionell eher etwa 1,25 Single-Thread-Cores oder, je nach Anwendung, einem entsprechenden Anteil davon.
    • Wenn man eine hochoptimierte, rechenintensive Aufgabe wie Videokompression laufen lässt, die Lüfter des Computers wie ein Jettriebwerk heulen und der Task-Manager trotzdem 50 % CPU-Auslastung anzeigt, ist diese Wahrnehmung nachvollziehbar.
    • In Intels neuen CPUs gibt es tatsächlich sowohl „P-Cores“ als echte Kerne als auch „E-Cores“ als minderwertige Kerne.
      Meiner Ansicht nach wurden E-Cores vor allem wegen Wärmeentwicklung und Die-Fläche eingeführt, nicht primär wegen Stromverbrauch oder Performance. Deshalb kaufe ich immer Chips ohne E-Cores; ich halte die für besser.
  • Ich frage mich, wie man nach solchen detaillierten technischen Artikeln suchen sollte.
    Ich habe genau zu diesem Thema gesucht, aber wie zu erwarten war, handelt es sich um Endnutzer-Technik, und die Suchergebnisse bestehen nur aus Anwenderartikeln, die nichts wirklich erklären.

    • Man kann https://hn.algolia.com verwenden. Unter der Annahme, dass die meisten Artikel dieser Art auf HN auftauchen oder dort erwähnt werden.
    • LLMs mit Webzugriff scheinen für solche Suchen recht gut geeignet zu sein. Zumindest helfen sie dabei, eine Richtung zu finden.
      Die angegebenen URLs sind allerdings meist Halluzinationen.
    • Ich weiß nicht, ob Google wegen dieses HN-Posts den plötzlichen Anstieg des Interesses an dem Artikel verfolgt, aber bei der Suche nach „how does simultaneous multi threading work“ tauchte dieser Blogpost bei mir ungefähr als 5. Ergebnis auf.
      Ich habe es in einem neuen privaten Firefox-Tab auf einem anderen Gerät geprüft; Tracking oder Caching lässt sich damit zwar nicht vollständig ausschließen, aber ich halte es für eine ziemlich vernünftige Annäherung.
  • Die Erklärung, dass „bei einem CPU-Kern mit aktiviertem SMT viele Puffer und Ausführungsressourcen von zwei logischen Prozessoren geteilt werden müssen, sodass diese Ressourcen selbst dann, wenn auf einem SMT-Kern nur ein Thread läuft, für diesen Thread nicht nutzbar sind und die potenzielle Leistung sinkt“, stimmt heute nicht mehr.
    Im SMT-Modus werden zwar ROB, Fetch-/Decode-Bandbreite usw. aufgeteilt, aber ich habe verschiedene SMT-Kerne gesehen, die im Nicht-SMT-Betrieb alles vollständig nutzbar machen.

    • Die x200-Serie der Phi-Prozessoren verhält sich genau so. Im Nicht-SMT-Modus bekommt ein Thread deutlich mehr Ressourcen als im 4-way-SMT-Modus.
  • Der zentrale Zweck von SMT ist es, die Auslastung der superskalaren Execution Engine zu maximieren.
    Ich frage mich, ob diese Entwicklung bedeutet, dass die Leute Superskalarität nicht mehr für so wichtig halten wie früher.

  • Insgesamt eine gute Zusammenfassung, aber stellenweise wirkte sie etwas vermischt.
    Ich würde gern mehr Praxis-Kniffe kennen, die Insider verwenden, selbst wenn sie nichts mit Sicherheit zu tun haben.

  • Die arme Bulldozer-Architektur von AMD wurde so sehr dafür kritisiert, kein SMT zu haben, und jetzt wenden sich alle von SMT ab.
    Natürlich weiß ich, dass Bulldozer weit mehr Probleme hatte als nur das fehlende SMT. Tatsächlich war es eher fast das genaue Gegenteil: mehrere Kerne teilten sich Dinge wie dieselbe ALU. Trotzdem: Wenn man nur etwas mehr Performance herausgeholt hätte, hätte man vielleicht in gewisser Weise etwas vorausgesehen.

    • Die PowerXX-Architektur wendet sich nicht von SMT ab.
      Power10 unterstützt derzeit effektiv SMT8 mit 8 Threads pro Kern, und angesichts der jahrelangen Weiterentwicklung SMT-zentrierter Designs glaube ich nicht, dass sie das aufgeben werden.
  • Bemerkenswert ist, dass auch die Recheneinheiten von GPUs typischerweise SMT in einer Größenordnung von 7 bis 10 Threads pro CU verwenden.
    Das hilft dabei, Latenzen zu verbergen.

    • Die meisten GPUs verwenden nicht SMT, sondern dessen Vorläufer, feingranulares Multithreading.
      In jedem Taktzyklus wird aus mehreren verfügbaren Threads eine Instruktion ausgewählt und gestartet, die nicht ausgelastete Ressourcen benötigt. Die meisten GPUs starten nicht mehrere Instruktionen pro Takt; mehrere Instruktionen können nach dem Start aber gleichzeitig weiterlaufen. Selbst wenn mehrere Instruktionen pro Takt gestartet werden, müssen sie möglicherweise zu getrennten Instruktionsklassen gehören, die unterschiedliche Ausführungsressourcen nutzen, etwa skalare und Vektor-Instruktionen.
      SMT, also simultanes Multithreading, bedeutet, dass in jedem Taktzyklus aus allen Threads viele Instruktionen gleichzeitig gestartet werden und diese Instruktionen um die mehreren Ausführungseinheiten einer superskalaren CPU konkurrieren, um möglichst viele Ausführungseinheiten beschäftigt zu halten. Für jede parallele Ausführungseinheit, etwa jede der sechs Integer-Addierer einer modernen CPU, wird separat entschieden, welche Instruktion aus einer Queue mit Instruktionen aller gleichzeitigen Threads ausgeführt wird.