Frage

Ich weiß, dass moderne CPUs außerhalb der Reihenfolge ausgeführt werden können, die Ergebnisse jedoch immer in Ordnung zurückziehen, wie von Wikipedia beschrieben.

"Out of ODer -Prozessoren füllen diese" Slots "rechtzeitig mit anderen Anweisungen, die bereit sind. Bestellt die Ergebnisse am Ende nach, um zu sehen, dass die Anweisungen als normal verarbeitet wurden."

Jetzt werden Speicherzäune bei der Verwendung von Multicore -Plattformen erforderlich x kann hier gedruckt werden.

Processor #1:
 while f == 0
  ;
 print x; // x might not be 42 here

Processor #2:
 x = 42;
 // Memory fence required here
 f = 1

Jetzt ist meine Frage, da außerhalb der Reihenfolge Prozessoren (Kerne bei Multicore-Prozessoren, von denen ich annehme) die Ergebnisse immer in Ordnung zurückzieht und dann die Notwendigkeit von Speicherzäunen ist. Sehen die Kerne eines Multicore-Prozessors nicht nur aus anderen Kernen, oder sehen auch Ergebnisse, die im Flug sind?

Ich meine, in dem Beispiel, das ich oben gegeben habe, wenn der Prozessor 2 die Ergebnisse schließlich zurückzieht, das Ergebnis von x sollte vorher kommen f, Rechts? Ich weiß, dass es bei der Ausführung außerhalb der Bestellung möglicherweise geändert hat f Vor x Aber es muss es vorher nicht in den Ruhestand gegangen sein x, Rechts?

Warum brauchen Sie jetzt bei der Pensionierung von Ergebnissen und des Cache-Kohärenzmechanismus in Form von Mechanismus in X86 jemals Speicherzäune?

War es hilfreich?

Lösung

Dieses Tutorial erklärt die Probleme: http://www.hpl.hp.com/techreports/compaq-dec/wrl-95-7.pdf

FWIW, bei dem Probleme mit der Speicherordnung bei modernen X86-Prozessoren auftreten, ist der Grund, dass das X86-Speicherkonsistenzmodell jedoch eine ziemlich starke Konsistenz bietet, aber explizite Hindernisse benötigt werden, um die Konsistenz von Read-After-Write zu bewältigen. Dies liegt an einem sogenannten "Ladenpuffer".

Das heißt, X86 ist nacheinander konsistent (schön und leicht zu argumentieren), außer dass Lasten frühere WRT -Stores neu bestellt werden können. Das heißt, wenn der Prozessor die Sequenz ausführt

store x
load y

dann im Prozessorbus kann dies als als angesehen werden

load y
store x

Der Grund für dieses Verhalten ist der oben erwähnte Geschäftspuffer, der ein kleiner Puffer für Schreibvorgänge ist, bevor sie in den Systembus gehen. Lastlatenz ist OTOH, ein kritisches Problem für die Leistung, und daher dürfen Lasten "die Warteschlange springen".

Siehe Abschnitt 8.2 in http://download.intel.com/design/processor/Manuals/253668.pdf

Andere Tipps

Der Speicherzaun stellt sicher, dass alle Änderungen an Variablen vor dem Zaun für alle anderen Kerne sichtbar sind, sodass alle Kerne eine aktuelle Ansicht der Daten haben.

Wenn Sie keinen Speicherzaun einsetzen, können die Kerne möglicherweise mit falschen Daten arbeiten. Dies ist insbesondere in den Szenarien zu sehen, in denen mehrere Kerne an denselben Datensätzen arbeiten würden. In diesem Fall können Sie sicherstellen, dass bei CPU 0 alle Änderungen am Datensatz für alle anderen Kerne sichtbar sind, die dann mit aktuellen Informationen arbeiten können.

Einige Architekturen, einschließlich des allgegenwärtigen X86/X64, geben mehrere Anweisungen zur Speicherbarriere an, einschließlich eines Anweisungen, der manchmal als "Vollzaun" bezeichnet wird. Ein vollständiger Zaun stellt sicher, dass alle Ladungs- und Speichervorgänge vor dem Zaun vor allen nach dem Zaun ausgegebenen Lasten und Geschäften begangen wurden.

Wenn ein Kern mit veralteten Daten auf dem Datensatz anfangen würde, wie könnte er jemals die richtigen Ergebnisse erzielen? Es konnte nicht egal, ob das Endergebnis vorgestellt werden sollte, wenn alles in der richtigen Reihenfolge geschehen ist.

Der Schlüssel befindet sich im Storepuffer, der zwischen dem Cache und der CPU liegt, und dies tut folgender:

Ladenpuffer für die Remote -CPUs unsichtbar

Mit dem Store -Puffer können Schreibvorgänge in Speicher und/oder Caches gespeichert werden, um die Interconnect -Zugriffe zu optimieren

Das bedeutet, dass die Dinge in diesen Puffer geschrieben werden, und dann wird der Puffer irgendwann in den Cache geschrieben. Daher könnte der Cache eine Ansicht von Daten enthalten, die nicht die jüngste sind, und daher wird eine andere CPU durch Cache -Kohärenz auch nicht die neuesten Daten haben. Ein Store -Puffer -Flush ist erforderlich, damit die neuesten Daten sichtbar sind.

BEARBEITEN:

Für den Code, den Sie als Beispiel verwendet haben, sagt Wikipedia Folgendes:

Eine Speicherbarriere kann vor der Zuordnung von Prozessor Nr. 2 zu F eingefügt werden, um sicherzustellen, dass der neue Wert von X für andere Prozessoren bei oder vor der Änderung des Wertes von F sichtbar ist.

Nur um ausdrücklich das zu machen, was in den vorherigen Antworten impliziert ist, ist dies richtig, unterscheidet sich jedoch von Speicherzugriffe:

CPUs kann außerhalb der Reihenfolge ausgeführt werden, aber sie ziehen die Ergebnisse immer in Ordnung zurück

Die Pensionierung der Anweisung ist von der Durchführung des Speicherzugriffs getrennt. Der Speicherzugriff kann zu einem anderen Zeitpunkt für den Ruhestand der Anweisung abgeschlossen sein.

Jeder Kern wird so handelt, als ob ein eigener Speicherzugriff im Ruhestand auftritt, aber andere Kerne sehen diese Zugriffe möglicherweise zu unterschiedlichen Zeiten.

(Auf X86 und Arm denke ich, dass nur Geschäfte beobachtet werden, aber z. B. Alpha kann einen alten Wert aus dem Gedächtnis laden. X86 SSE2 hat Anweisungen mit schwächeren Garantien als das normale X86 -Verhalten).

Ps. Aus dem Gedächtnis konnte der verlassene Sparc-Gestein tatsächlich außerordentlich in den Ruhestand treten, sie verbrachte Kraft und Transistoren fest, wann dies harmlos war. Es wurde wegen Stromverbrauchs und Transistorzahl aufgegeben ... Ich glaube nicht, dass eine allgemeine CPU mit außerordentlicher Ruhestand auf dem Markt gekauft wurde.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top