AMD Genesis: Angeblich Threadripper 4000 in AIDA64 gesichtet

Auf Hardware-Ebene gibt es keine "Hauptthreads". Müsste SMT erst bei jedem Thread den Rang prüfen, könnte es nicht schnell genug schalten und allgemein würde ein System mit derartiger Priorisierung schnell einfrieren, wenn ein hochrangiger Thread die Ausführung aller anderen verhindern würde. Desweiteren Kostet die Verwaltung vieler Threads einer Anwendung einfach Rechenzeit und durch das Vorhalten weiterer Daten reduziert für andere Tasks verfügbare Cache-Menge. All das lohnt sich, wenn andernfalls Rechenzeit brach liegt, während aufwendige Aufgaben in der Warteschleife liegen. Aber wenn die Recheneinheiten bereits vollständig ausgelastet sind oder wenn die Abspaltung weiterer Aufgaben in zusätzliche Threads beinahe genauso viel Synchronisationsarbeit im Mutterhtread generiert, wie eine direkte Berechnung in diesem gekostet hätte, dann reduziert SMT die effektive Leistung. Und je höher der SMT-Faktor, deso eher tritt dieser Fall ein.
 
Dass es auf der Ebene keine echte Priorisierung gibt, ist mir soweit klar. Aber die gewählten Kriterien für einen Wechsel können halt mehr oder weniger "fair" sein, was jeweils eigene Vor- und Nachteile mit sich bringt. In einem nicht fairen Verfahren, würde ein schwerer Thread ("Hauptthread") vermutlich den allergrößten Teil der Zeit bekommen, wodurch ein anderer verhungern könnte. Die Rechnungen, die für SMT selbst gemacht werden müssen, sollten nicht die regulären Rechenwerke betreffen, sondern in der SMT-Logik enthalten sein, also Platz aber keine Zeit kosten. Wie du schon sagst, muss das alles sehr schnell gehen. Das sollten Logiken sein wie "wenn der aktive Thread stallt, wechsle auf den nächsten" oder "wechsle alle X Takte" oder eine Kombination von beiden.

So richtig leuchtet mir das nicht ein, warum es wirklich Nachteile geben sollte, außer dadurch, dass das Scheduling versagt. Die Threads müssten ohne SMT ja auch laufen und würden auch Cache belegen und hätten auch Kommunikationsaufwand. Idealerweise spart man sich lediglich einige aufwändige Kontextwechsel und hat eine höhere Auslastung der Rechenwerke, aber wenn der Scheduler schwere Threads zusammenpackt, ächzen halt ein paar Kerne und ein paar drehen Däumchen. Das ist im Moment das einzige was mir wirklich einleuchtet, was mit SMT passieren kann und ohne nicht. Das sollte aber eigentlich lösbar sein, wenn das OS weiß, welche logischen Kerne jeweils einen physischen ausmachen. Zumindest, wenn die Last der einzelnen Threads nicht wild schwankt.
 
Solange Berechnungen in einem Thread laufen, stehen die Ergebnisse dem gleichen Thread gleich wieder zur Verfügung und das Caching-System kann systematisch die wichtigsten Inhalte bereit halten. Verteilt man die gleichen Berechnungen auf zwei Threads wird der Cache zwischen diesen geteilt – die Logik kann nicht entscheiden, ob ein Thread mehr Cache-Bedarf als der andere hat, es ist schon schwer genug die wichtigsten Daten innerhalb eines Threads zu erkennen. Und wenn Daten von einem Thread an einen anderen übergeben werden sollen, müssen sie zunächst gespeichert und wieder geladen werden. Auch wenn das alles im Cache abläuft, kostet es schon dutzdende bis hunderte Taktzyklen gegenüber einem Weiterarbeiten innerhalb der Register.

Der Scheduler selbst dürfte gar kein Bewusstsein für das Konzept "Thread" haben. Der schickt die vom Decoder angelieferten Micro Ops in die Ausführungseinheiten und kann bestenfalls abhängige/spekulative Befehle nachrangig behandeln. Aber derartige Entscheidungen werden innerhalb eines Taktzyklus getroffen, selbst unter Berücksichtigung des kompletten Decodings steht viel zu wenig Zeit für eine Überprüfung der Thread-Eigenschaften zur Verfügung. Wie nach einschlägigen Hacks bekannt sein sollte, lässt zumindest Intel selbst Zugangsberechtigungen erst parallel zur eigentlichen Berechnung überprüfen, weil es weniger Leistung kostet, wenn ein Teil der Berechnungen wieder verworfen werden muss, als wenn man vor dem Start jeder Berechnung erst eine komplexe Entscheidung treffen muss.
 
Wenn zwei Threads auf einem Kern laufen und den selben Cache benutzen, greifen sie vermutlich sogar auf die gleichen Cacheeinträge zu, wenn sie sich Daten teilen. Cache bildet ja den Speicher teilweise ab und Interthreadkommunikation wird in manchen Systemen sogar über Caches realisiert, wenn ich mich recht entsinne. Und erkannt ob Daten wichtig sind wird, wenn darauf zugegriffen wird und zum Aussortieren wird doch seit Ewigkeiten der LRU-Algorithmus verwendet.

OK, wir reden von verschiedenen Schedulern. Ich meinte den vom OS. Klar, der in der CPU hat keine Zeit, da kommen die Logiken zum Einsatz, die ich oben auch erwähnte. Mehr als ein Zähler oder ein paar Signale, die die ALUs über ihren Arbeitszustand von sich geben, ist da nicht drin.
 
Der Windows-Scheduler hat mit SMT überhaupt nichts zu tun. Der wäre ja seinerseits ein extra Thread, der erst einmal bearbeitet werden muss und bis dahin ist die Auslastungslücke lange vorbei. SMT arbeitet mit Fenstern, die maximal 5-10 Taktzyklen lang sind. Würde man 15-20 Taktzyklen für den Wechsel brauchen, läge ja oft schon das Ergebnis vor, auf das der zuvor ausgeführte Thread gewartet hat.

Ob zwei Threads auf die gleichen Daten zugreifen, hängt natürlich von der Art der Threads ab. Für SMT wäre es eher von Nachteil, da die Threads offensichtlichen von den Ergebnissen des jeweils anderen abhängig sind und immer wieder aufeinander warten müssen. Grundsätzlich ist es aber zumindest bei Intel auf L1- und meinem Wissen nach auch L2-Ebene so, dass der Prozessor für die gerade laufenden Threads Daten vorrätig zu halten versucht und dabei teilt er den verfügbaren Speicherplatz ein. Je weniger Threads parallel laufen, desto mehr Daten können pro Thread für den Fall einer etwaigen Wiederverwendung zwischengespeichert werden.
 
Naja, er kann wissen, welchen logischen Kernen er welche Aufgaben zuteilt. Er kann das SMT selbst nicht beeinflussen, aber er kann auf die Besonderheiten der Technik und der Architektur der verbauten CPU Rücksicht nehmen. Er weiß ja, welche Prozesse zum aktuellen Zeitpunkt rechenintensiv sind und vielleicht nicht zusammen auf einem physischen Kern landen sollten. Er könnte so z.B. die Threads, die sich in der jüngsten Vergangenheit als am rechenintensivsten rausgestellt haben nur auf jeden zweiten logischen Kern legen, wenn er weiß, dass immer zwei logische Kerne einen physischen ausmachen. Architekturmäßig könnte man für Zen-CPUs zum Beispiel bestimmen, dass der Leidensdruck, der von der aktuellen Verteilung des Workloads ausgehen muss etwas höher sein muss, bevor der Thread auf ein anderes Chiplet verlegt wird.

Ehrlich gesagt glaube ich, dass die Verteilung des Speicherplatzes automatisch durch die Benutzung erfolgt. Ein Cache macht ja nichts anderes, als die Daten und die Speicheradresse von Speicheradresse XY an Cacheposition X+(0...n) zu speichern und bei erneutem Bedarf wieder bereitzustellen, um so den Speicherzugriff zu vermeiden, wobei X das Cachetag, XY eine vollständige Speicheradresse und n die Assoziativität des Caches ist. Dadurch wird bei einer Benutzung von einem Cache durch mehrere Kerne (also in der Regel ab L2) automatisch den Kernen mit der meisten Benutzung der meiste Cache "zugeteilt".

Hier ist ein Artikel von Intel zu dem Thema: Software Techniques for Shared-Cache Multi-Core Systems | Intel(R) Software
 
Zurück