Wann sollte ich _mm_sfence _mm_lfence und _mm_mfence verwenden?

8

Ich habe den "Intel Optimization guide Guide für Intel Architektur" gelesen.

Ich habe aber immer noch keine Ahnung, wann ich es benutzen soll _mm_sfence () _mm_lfence () _mm_mfence ()

Könnte mir jemand die Erklärung geben?

    
prgbenz 27.12.2010, 09:35
quelle

2 Antworten

1

Vorbehalt : Ich bin kein Experte darin. Ich versuche das immer noch selbst zu lernen. Aber da niemand in den letzten zwei Tagen geantwortet hat, scheint es, dass Experten auf Memory Fence Anweisungen nicht reichlich vorhanden sind. Also hier ist mein Verständnis ...

Intel ist ein schwach geordnetes Speichersystem. Das bedeutet, dass Ihr Programm möglicherweise

ausführt %Vor%

Die Änderung von idx kann jedoch global sichtbar sein (z. B. für Threads / Prozesse, die auf anderen Prozessoren ausgeführt werden), bevor die Änderung in array erfolgt. Durch das Platzieren von sfence zwischen den beiden Anweisungen wird sichergestellt, dass die Schreibvorgänge an den FSB gesendet werden.

Inzwischen läuft ein anderer Prozessor

%Vor%

hat möglicherweise den Speicher für Array zwischengespeichert und hat eine veraltete Kopie, aber erhält die aktualisierte idx aufgrund eines Cache-Fehltreffers. Die Lösung besteht darin, lfence gerade vorher zu verwenden, um sicherzustellen, dass die Lasten synchronisiert sind.

Dieser Artikel oder dieser Artikel gibt möglicherweise bessere Informationen

    
Mark Borgerding 29.12.2010, 14:04
quelle
3

Hier ist mein Verständnis, hoffentlich genau und einfach genug, um Sinn zu ergeben:

(Itanium) Die IA64-Architektur ermöglicht die Ausführung von Speicherlese- und -schreibvorgängen in beliebiger Reihenfolge, sodass die Speicherreihenfolge aus der Sicht eines anderen Prozessors nicht vorhersehbar ist, es sei denn, Sie verwenden Zäune, um die Schreibvorgänge in einer sinnvollen Reihenfolge zu erzwingen .

Ab hier spreche ich von x86, x86 ist stark geordnet.

Bei x86 garantiert Intel nicht, dass ein auf einem anderen Prozessor ausgeführter Speicher auf diesem Prozessor immer sofort sichtbar ist. Es ist möglich, dass dieser Prozessor spekulativ die Last (Lesen) gerade früh genug ausgeführt hat, um den Speicher des anderen Prozessors zu verfehlen (schreiben).

Gesperrte Lese- / Modifizierungs- / Schreibbefehle sind vollständig sequenziell konsistent, so dass Sie selten Zäune auf x86 verwenden müssen. Aus diesem Grund behandeln Sie im Allgemeinen bereits die Speicheroperationen des anderen Prozessors, weil ein gesperrtes xchg oder cmpxchg das alles abgleichen wird.

Soweit ich das verstanden habe, entlädt lfence die Speicher-Lade-Warteschlange und wartet darauf, dass die Pipeline der Lade-Einheit beendet wird, was auch immer gerade ausgeführt wird. mfence geht weiter und wartet auf alle Lese- und Schreibvorgänge im Speicher, sfence macht dasselbe nur für Speicher (und löscht Schreibkombinierer).

Im Wesentlichen verwirft lfence spekulativ ausgeführte Lasten. Lasten, die zuvor spekulativ ausgeführt wurden, werden erneut ausgegeben. In der Praxis ist sfence am wenigsten notwendig, normalerweise ist es nicht notwendig, es sei denn, man verwendet Write-Combining-Speicher, etwas, was man selten tut, wenn man kein Kernel-Mode (Treiber) -Entwickler ist.

Zusammenfassend gesagt, Algorithmen, die gesperrte Anweisungen wie xchg oder xadd oder cmpxchg usw. verwenden, funktionieren ohne Zäune, da die gesperrte Anweisung (in den meisten Fällen) alles zum Synchronisieren ausführt. Jeder knifflige Code, der zum Beispiel Code-Pfade hat, die diese Lock-Instruktionen nicht verwenden, könnte irgendwo lfence benötigen, um zu vermeiden, dass ein Speicher von einem anderen Prozessor verloren geht. Code, der heikel ist, ist selten und keine gute Übung, kann aber in extrem heißen Codepfaden notwendig sein.

    
doug65536 11.10.2012 23:45
quelle

Tags und Links