Wann sollte ich _mm_sfence, _mm_lfence und _mm_mfence verwenden?

Lesezeit: 6 Minuten

Wann sollte ich mm sfence mm lfence und mm mfence verwenden
prgbenz

Ich habe den “Intel Optimization Guide Guide For Intel Architecture” gelesen.

Allerdings habe ich immer noch keine Ahnung, wann ich es verwenden sollte

_mm_sfence()
_mm_lfence()
_mm_mfence()

Könnte jemand erklären, wann diese beim Schreiben von Multithread-Code verwendet werden sollten?

  • @BeeOnRope: Ich habe diese Frage aktualisiert / neu markiert, um zu stellen, was meiner Meinung nach die eigentliche Frage war: über diese Eigenheiten in Multithread-Code (die ursprünglichen Tags enthielten Parallelverarbeitung.) Es gibt viele Fragen und Antworten zu den Maschinenanweisungen, aber diese ist anders, weil das Mem-Modell von C++ schwach ist. Sie möchten eine Möglichkeit, ein Acquiring-Load oder Release-Store durchzuführen ohne wodurch der Compiler ein nutzloses ausgibt lfence oder sfence, stoppt einfach die Neuordnung zur Kompilierzeit. (preshing.com/20120625/memory-ordering-at-compile-time). Verwenden Sie 2018 natürlich nur C11 stdatomic / C++11 std::atomic.

    – Peter Cordes

    9. Juni 2018 um 16:02 Uhr


  • @PeterCordes Sie denken also, dass es bei dieser Frage in gewisser Weise um Compiler-Barrieren geht? Das heißt, eine gute Antwort könnte in etwa so lauten lfence und sfence Anweisungen sind im Allgemeinen auf der x86-Assembly-Ebene nutzlos, aber Sie möchten vielleicht eine Compiler-Barriere einfügen, um Compiler-Neuordnungen zu verhindern? Übrigens kenne ich für die meisten Compiler keine feinkörnigeren als vollständigen Compiler-Barrieren, aber MSVC hat sie _[Read|Write]Barrier. Ich denke, Sie könnten einige Arten von Barrieren mit Inline-Asm und cleverem Einsatz von Einschränkungen erfinden.

    – BeeOnRope

    9. Juni 2018 um 16:46 Uhr

  • std::atomic_signal_fence(std::memory_order_release) mit gcc scheint es sogar nicht-atomare Variablen zu ordnen, aber das kann ein Implementierungsdetail sein. Ich habe nicht unter die Haube geschaut.

    – Peter Cordes

    9. Juni 2018 um 16:49 Uhr

  • @PeterCordes – es soll nicht-atomare Variablen bestellen, oder? Genau wie die meisten mo_ Ordnungen auf atomaren Variablen ordnen auch irgendwie die umgebenden nicht-atomaren Zugriffe. Für Zäune ist die Reihenfolge von nicht-atomaren Variablen die hauptsächlich Zweck, denke ich. Vielleicht habe ich nicht verstanden, was du meinst…

    – BeeOnRope

    9. Juni 2018 um 16:56 Uhr


  • Es ist möglich, dass sfence; lfencewenn sfence den Speicherpuffer leert, könnte dafür sorgen, dass Speicher für andere Threads schneller erscheinen, indem andere nachfolgende Ladeaktivitäten effektiv angehalten werden, die um L1-Bandbreite und andere Ressourcen wie LFBs konkurrieren könnten. Auch nachträglich Laden Aktivität könnte auf diese Weise konkurrieren, obwohl dies weniger wahrscheinlich erscheint (es hängt von den Details des RFO-Prefetching ab). Dies ist jedoch ziemlich unklar und scheint in der Praxis keine große Rolle zu spielen. Könntest du auch verwenden pauseobwohl es auf Skylake+ viel langsamer ist.

    – BeeOnRope

    10. Juni 2018 um 21:22 Uhr


  • Brauchst du normalerweise nicht lfence je. Du brauchst nur sfence nach schwach geordnet movnt Streaming-Shops. Du brauchst mfence (oder ein locked-Operation), um sequentielle Konsistenz zu erhalten, anstatt nur freizugeben/erfassen. (Sehen Erinnerungsumordnung auf frischer Tat ertappt zum Beispiel.)

    – Peter Cordes

    2. Juli 2017 um 1:39 Uhr

  • Sie brauchen normalerweise lfence weil C++-Compiler.

    – Marek Vitek

    9. Juli 2017 um 20:59 Uhr

  • lfence verwirft keine spekulativ ausgeführten Stores. lfence ist nur ein Befehlsstrom-Serialisierer: Er wartet, bis alle vorherigen Befehle (jeglicher Art, nicht nur Speicherzugriff) zurückgezogen wurden, bevor er fortfährt, und während des Wartens werden keine späteren Befehle ausgeführt. Es ist nicht nützlich, um Speicherzugriffe in normalen Programmen im Benutzermodus zu ordnen. Es wird dort hauptsächlich als OoO-Barriere verwendet, um kleine Coderegionen konsistenter zu profilieren. sfence ist ähnlich nicht sinnvoll, außer in Verbindung mit sogenannten “nicht-temporalen” Speichern, wie z movntq.

    – BeeOnRope

    8. Juni 2018 um 22:33 Uhr


  • @ Peter Cordes denke ich lfence stoppt auch das Problem (Intel-Begriffe: dh das Senden von ops zu der Planer). Sobald sich die uops im Planer befinden, ist es zu schwierig, sie vorher/nachher zu trennen, so scheint es (von Patenten usw.). lfence stoppt einfach das Problem, bis es in den Ruhestand geht. Ich denke also, dass das Umbenennen aufhört, aber alles davor kann weiterlaufen und sich im IDQ anstellen.

    – BeeOnRope

    9. Juni 2018 um 17:10 Uhr


  • @BeeOnRope: Das würde Sinn machen. Ich dachte darüber nach, ob es testbar ist. Vielleicht mit einem Latenzengpass nach einer Reihe von NOPs, und prüfen Sie, ob mehr NOPs den Durchsatz verringern. Wenn uops von nach einem lfence alle im Scheduler sitzen und darauf warten, gestartet werden zu dürfen, dann spielen mehr uops keine Rolle, es sei denn, wir schaffen einen Front-End-Engpass, der größer ist als die Dep-Kette.

    – Peter Cordes

    9. Juni 2018 um 17:20 Uhr

  • Erwähnenswert ist vielleicht, dass der Anwendungsfall für die Speicherbestellung für lfence ist nach Lasten aus dem Videospeicher, vor allem mit movntdqa, oder irgendetwas anderes, das WC zugeordnet ist. Sie könnten also sagen: “Wenn Sie Ihrem User-Space-Programm kein Video-RAM zugeordnet haben, brauchen Sie es nicht lfence“. Ich bin sicher, die Leute werden sich fragen, wann es jemals nützlich ist; ich weiß, dass ich es tun würde, also ist ein kleiner Hinweis / eine Zusammenfassung nützlich. Der Benutzerraum kann Video-RAM mit der Hilfe des Kernels zuordnen …

    – Peter Cordes

    9. Juni 2018 um 8:12 Uhr


  • Ich versuche absichtlich, diese Antwort ziemlich kurz und direkt zu halten, auch wenn dies vielleicht auf Kosten der nicht erschöpfenden Genauigkeit geht, wenn es um alles Mögliche geht lfence verwenden. Das heißt, ich möchte keine Antwort im @PeterCordes-Stil geben, die notwendigerweise alle Möglichkeiten abdeckt und oft mehr Prosa dafür ausgibt als der 99% -Fall (nicht, dass dies ein Problem wäre, ich schreibe auch solche Antworten – aber ich tue es will es hier nicht). Gibt es Anwendungen im Benutzermodus, die WC-Video-RAM in ihren Adressraum abbilden? Wahrscheinlich, aber ein sehr kleiner Bruchteil. Gibt es einige von denen, die brauchen …

    – BeeOnRope

    9. Juni 2018 um 16:36 Uhr

  • … Load-Load-Reihenfolge (aber keine anderen Arten der Reihenfolge) in Bezug auf das Laden aus dem Video-RAM, und wer verwendet nicht bereits eine Art von Synchronisation, die dies bietet? Dies scheint ein kleines Stück des früheren kleinen Stücks zu sein. Aus dieser winzigen Gruppe, für wie viele lfence interessant in dem Sinne, dass es jede Art von Verbesserung bietet mfence? Ich weiß nicht, aber ich denke, es ist sehr klein. Aus Neugier schon mal gesehen lfence in einem echten Programm, das sich mit WC-Lesevorgängen aus dem Video-RAM befasst? Übrigens, wenn ich noch einen hinzufügen wollte lfence Verwenden Sie es wäre Kernschmelze / Gespensterminderung.

    – BeeOnRope

    9. Juni 2018 um 16:38 Uhr


  • @PeterCordes – sieht gut aus. Ich habe mich auch über den Zweck gewundert lfence. Ich glaube nicht, dass es tatsächlich durch “Mapping von WC-Speicher in den Benutzerbereich” erklärt wird. Es scheint mir, dass diese Anweisungen zu einer Zeit eingeführt wurden, in der “große Hoffnung” auf nicht-temporäre Anweisungen im WB-Speicher bestand, und vielleicht, als das Speichermodell nicht wirklich festgenagelt war und die Intel-Architekten möglicherweise immer noch eine Last-Lade-Neuordnung zulassen wollten unter bestimmten Umständen (sogar außerhalb von NT-Lasten) im WB-Modus, oder vielleicht erwogen sie einen anderen leistungsstärkeren, schwächeren Modus wie WB+, der mehr Neuordnungen ermöglichte.

    – BeeOnRope

    10. Juni 2018 um 20:20 Uhr

  • Das hat irgendwie nicht geklappt: Sie haben sich an ein starkes Modell gehalten, vielleicht nur standardmäßig, da sich die Leute wahrscheinlich bereits auf bestehende Verhaltensweisen verlassen haben, weil sie es in den ersten MP-Systemen nicht sehr gut definiert haben (obwohl sie mehrere Iterationen brauchten, um wirklich sich für ein Modell entscheiden und selbst heute ist es schwer, das Dokument zu lesen). Also dann denke ich lfence war nur irgendwie verwaist – der WC-Video-RAM-Fall scheint mir da unwahrscheinlich mfence dient demselben Zweck, und solche Szenarien gab es schon lange vorher lfence (waren in der Tat häufiger in DOS und nicht geschützten Betriebssystemen). Das ist reine Spekulation…

    – BeeOnRope

    10. Juni 2018 um 20:23 Uhr


916640cookie-checkWann sollte ich _mm_sfence, _mm_lfence und _mm_mfence verwenden?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy