Was bedeutet "nicht zeitlicher" Speicherzugriff in x86?


123

Dies ist eine etwas untergeordnete Frage. In der x86-Assembly gibt es zwei SSE-Anweisungen:

MOVDQA xmmi, m128

und

MOVNTDQA xmmi, m128

Das IA-32 Software Developer's Manual besagt, dass der NT in MOVNTDQA für Non-Temporal steht steht und ansonsten dasselbe wie MOVDQA ist.

Meine Frage ist, was bedeutet nicht-zeitlich ?


6
Beachten Sie, dass SSE4.1 MOVNTDQA xmmi, m128eine NT-Last ist, während alle anderen NT-Anweisungen außer gespeichert sind prefetchnta. Die akzeptierte Antwort hier scheint nur über Geschäfte zu sprechen. Dies ist, was ich über NT-Lasten auftauchen konnte . TL: DR: Hoffentlich macht die CPU mit dem NT-Hinweis etwas Nützliches, um die Cache-Verschmutzung zu minimieren, aber sie überschreibt nicht die stark geordnete Semantik des "normalen" WB-Speichers, so dass sie den Cache verwenden müssen.
Peter Cordes

5
Update: NT- Ladevorgänge können nur in UCSW-Speicherbereichen auf den meisten CPUs (z. B. Intel SnB-Familie) nützlich sein. NT / Streaming- Speicher funktionieren jedoch definitiv mit normalem Speicher.
Peter Cordes

4
@ Peter: Du meinst USWC-Speicher, oder? Ich habe noch nie von UCSW- oder USWC-Speicher gehört. Das falsche Akronym zu googeln war nicht hilfreich :-)
Andrew Bainbridge

4
@ AndrewBainbridge: Ja, das Attribut WC-Speichertyp. Nicht zwischenspeicherbare spekulative Schreibkombination. Ich glaube, ich habe UnCacheable groß geschrieben und mich daran erinnert, dass es 4 Buchstaben lang sein sollte. : P
Peter Cordes

Antworten:


147

Nicht-zeitliche SSE-Anweisungen (MOVNTI, MOVNTQ usw.) folgen nicht den normalen Cache-Kohärenzregeln. Daher müssen nicht-zeitlichen Speichern eine SFENCE-Anweisung folgen, damit ihre Ergebnisse von anderen Prozessoren rechtzeitig gesehen werden können.

Wenn Daten erzeugt und nicht (sofort) wieder verbraucht werden, wirkt sich die Tatsache, dass Speicherspeicheroperationen zuerst eine vollständige Cache-Zeile lesen und dann die zwischengespeicherten Daten ändern, nachteilig auf die Leistung aus. Durch diesen Vorgang werden Daten aus den Caches verschoben, die möglicherweise erneut benötigt werden, und zwar zugunsten von Daten, die nicht bald verwendet werden. Dies gilt insbesondere für große Datenstrukturen wie Matrizen, die gefüllt und später verwendet werden. Bevor das letzte Element der Matrix gefüllt wird, werden die ersten Elemente durch die schiere Größe entfernt, wodurch das Zwischenspeichern der Schreibvorgänge unwirksam wird.

Für diese und ähnliche Situationen bieten Prozessoren Unterstützung für nicht-zeitliche Schreibvorgänge. Nicht zeitlich begrenzt bedeutet in diesem Zusammenhang, dass die Daten nicht bald wiederverwendet werden, sodass kein Grund besteht, sie zwischenzuspeichern. Diese nicht-zeitlichen Schreibvorgänge lesen keine Cache-Zeile und ändern sie dann. Stattdessen wird der neue Inhalt direkt in den Speicher geschrieben.

Quelle: http://lwn.net/Articles/255364/


15
Schöne Antwort, ich möchte nur darauf hinweisen, dass bei der Art von Prozessor mit NT-Anweisungen, selbst bei einer nicht-nicht-zeitlichen Anweisung (dh einer normalen Anweisung), der Zeilen-Cache nicht "gelesen und dann geändert" wird. Für einen normalen Befehl, der in eine Zeile schreibt, die sich nicht im Cache befindet, ist eine Zeile im Cache reserviert und eine Maske zeigt an, welche Teile der Zeile aktuell sind. Diese Webseite nennt es "kein Stall im Laden": ptlsim.org/Documentation/html/node30.html . Ich konnte keine genaueren Referenzen finden, ich habe nur von Leuten davon gehört, deren Aufgabe es ist, Prozessorsimulatoren zu implementieren.
Pascal Cuoq

2
Tatsächlich ist ptlsim.org eine Website über einen zyklusgenauen Prozessorsimulator, genau das gleiche, was die Leute tun, die mir von "no Stall on Store" erzählt haben. Ich sollte sie auch erwähnen, falls sie diesen Kommentar jemals sehen sollten: unisim.org
Pascal Cuoq

1
Aus den Antworten und Kommentaren hier stackoverflow.com/questions/44864033/... scheint es SFENCEnicht erforderlich sein. Zumindest im selben Thread. Könnten Sie auch schauen?
Serge Rogatch

1
@SergeRogatch hängt davon ab, von welchem ​​Szenario Sie sprechen, aber ja, es gibt Szenarien, in denen sfenceNT-Stores erforderlich sind, während dies nur für normale Stores erforderlich ist. NT-Stores werden nicht in Bezug auf andere Stores (NT oder nicht) bestellt, wie von anderen Threads gesehen , ohne ein sfence. Für Lesevorgänge aus demselben Thread, in dem die Stores ausgeführt wurden, benötigen Sie jedoch nie sfence: Ein bestimmter Thread sieht seine eigenen Stores immer in Programmreihenfolge, unabhängig davon, ob es sich um NT-Stores handelt oder nicht.
BeeOnRope

40

Espo ist ziemlich genau richtig. Ich wollte nur meine zwei Cent hinzufügen:

Die "nicht zeitliche" Phrase bedeutet fehlende zeitliche Lokalität. Caches nutzen zwei Arten von Lokalitäten - räumliche und zeitliche. Wenn Sie eine nicht-zeitliche Anweisung verwenden, signalisieren Sie dem Prozessor, dass Sie nicht erwarten, dass das Datenelement in naher Zukunft verwendet wird.

Ich bin etwas skeptisch gegenüber der handcodierten Assembly, die die Anweisungen zur Cache-Steuerung verwendet. Nach meiner Erfahrung führen diese Dinge zu mehr bösen Fehlern als jede effektive Leistungssteigerung.


Frage zu "Handcodierte Assembly, die die Anweisungen zur Cache-Steuerung verwendet". Ich weiß, dass Sie ausdrücklich "handcodiert" gesagt haben, was ist mit so etwas wie einer JavaVM? Ist das ein besserer Anwendungsfall? Der JavaVM / Compiler hat das statische und dynamische Verhalten des Programms analysiert und verwendet diese nicht-zeitlichen Anweisungen.
Pat

4
Das Ausnutzen bekannter Lokalitätseigenschaften (oder deren Fehlen) Ihrer Problemdomäne, Ihres Algorithmus oder Ihrer Anwendung sollte nicht gemieden werden. Das Vermeiden von Cache-Verschmutzung ist in der Tat eine sehr attraktive und effektive Optimierungsaufgabe. Auch warum die Abneigung gegen Montage? Es gibt eine Vielzahl von Gewinnmöglichkeiten, die ein Compiler unmöglich nutzen kann
awdz9nld

5
Es ist definitiv wahr, dass ein sachkundiger Low-Level-Programmierer einen Compiler für kleine Kernel übertreffen kann. Dies ist großartig für die Veröffentlichung von Artikeln und Blogposts, und ich habe beides getan. Sie sind auch gute didaktische Werkzeuge und helfen zu verstehen, was "wirklich" vor sich geht. Nach meiner Erfahrung wird in der Praxis, in der ein echtes System mit vielen Programmierern daran arbeitet und Korrektheit und Wartbarkeit wichtig sind, der Nutzen einer Codierung auf niedriger Ebene fast immer durch die Risiken aufgewogen.
Pramod

4
@Pramod dasselbe Argument lässt sich leicht auf die Optimierung im Allgemeinen verallgemeinern und ist nicht wirklich Gegenstand der Diskussion - klar, dass ein Kompromiss bereits in Betracht gezogen oder auf andere Weise als irrelevant angesehen wurde, da es sich bereits um nicht-zeitliche Anweisungen handelt
awdz9nld

7

Gemäß dem Softwareentwicklerhandbuch für Intel® 64- und IA-32-Architekturen, Band 1: Grundlegende Architektur, Kapitel "Programmieren mit Intel Streaming SIMD Extensions (Intel SSE)":

Caching von zeitlichen und nicht-zeitlichen Daten

Daten, auf die von einem Programm verwiesen wird, können zeitlich (Daten werden erneut verwendet) oder nicht zeitlich (Daten werden einmal referenziert und in naher Zukunft nicht wiederverwendet) sein. Beispielsweise ist Programmcode im Allgemeinen zeitlich begrenzt, wohingegen Multimediadaten wie die Anzeigeliste in einer 3D-Grafikanwendung häufig nicht zeitlich begrenzt sind. Um die Caches des Prozessors effizient zu nutzen, ist es im Allgemeinen wünschenswert, zeitliche Daten und nicht nicht-zeitliche Daten zwischenzuspeichern. Das Überladen der Caches des Prozessors mit nicht-zeitlichen Daten wird manchmal als "Verschmutzung der Caches" bezeichnet. Die Anweisungen zur Steuerung der Cachefähigkeit von SSE und SSE2 ermöglichen es einem Programm, nicht-zeitliche Daten auf eine Weise in den Speicher zu schreiben, die die Verschmutzung von Caches minimiert.

Beschreibung der nicht-zeitlichen Lade- und Speicheranweisungen. Quelle: Intel 64- und IA-32-Architekturen Software-Entwicklerhandbuch, Band 2: Befehlssatzreferenz

LOAD (MOVNTDQA - Nicht zeitlich ausgerichteten Doppelquadword-Hinweis laden)

Lädt ein Doppelquadwort vom Quelloperanden (zweiter Operand) zum Zieloperanden (erster Operand) unter Verwendung eines nicht-zeitlichen Hinweises, wenn die Speicherquelle vom WC-Speichertyp (... Schreibkombination) ist [...]

[...] Der Prozessor liest weder die Daten in die Cache-Hierarchie, noch holt er die entsprechende Cache-Zeile aus dem Speicher in die Cache-Hierarchie.

Beachten Sie, dass es, wie Peter Cordes kommentiert, im normalen WB-Speicher (Write-Back) auf aktuellen Prozessoren nicht nützlich ist, da der NT-Hinweis ignoriert wird (wahrscheinlich, weil es keine NT-fähigen HW-Prefetcher gibt) und die vollständige, stark geordnete Ladesemantik gilt . prefetchntakann als verschmutzungsreduzierende Last aus dem WB-Speicher verwendet werden

STORE (MOVNTDQ - Gepackte Ganzzahlen mit nicht-zeitlichem Hinweis speichern)

Verschiebt die gepackten Ganzzahlen im Quelloperanden (zweiter Operand) unter Verwendung eines nicht-zeitlichen Hinweises zum Zieloperanden (erster Operand), um das Zwischenspeichern der Daten während des Schreibens in den Speicher zu verhindern.

[...] Der Prozessor schreibt weder die Daten in die Cache-Hierarchie, noch ruft er die entsprechende Cache-Zeile aus dem Speicher in die Cache-Hierarchie.

Verwenden der in Cache Write Policies and Performance definierten Terminologie können sie als Write-Around (No-Write-Allocate, No-Fetch-On-Write-Miss) betrachtet werden.

Schließlich kann es interessant sein, John McAlpins Notizen zu nicht-temporären Speichern zu lesen .


3
SSE4.1 macht MOVNTDQAnur etwas Besonderes in WC-Speicherbereichen (nicht zwischenspeicherbar), z. B. Video-RAM. Es ist im normalen WB-Speicher (Write-Back) auf der aktuellen HW überhaupt nicht nützlich, der NT-Hinweis wird ignoriert und es gilt die vollständige, stark geordnete Ladesemantik. prefetchntaaber als Verschmutzung- kann nützlich sein, zu reduzieren Belastung von WB - Speichern. Unterstützen aktuelle x86-Architekturen nicht-zeitliche Lasten (aus "normalem" Speicher)? .
Peter Cordes

2
Das ist richtig, NT-Speicher funktionieren gut im WB-Speicher, sind schwach geordnet und normalerweise eine gute Wahl zum Schreiben großer Speicherbereiche. NT-Lasten sind es jedoch nicht. Das x86-Handbuch auf Papier ermöglicht es dem NT-Hinweis, etwas für das Laden aus dem WB-Speicher zu tun, aber in aktuellen CPUs tut er nichts . (Wahrscheinlich, weil es keine NT-fähigen HW-Prefetchers gibt.)
Peter Cordes

Ich habe diese relevanten Informationen zur Antwort hinzugefügt. Vielen Dank.
Chus

1
@ LewisKelsey: NT- Speicher überschreiben den Speichertyp. Deshalb können sie im WB-Speicher schwach geordnet werden. Der Haupteffekt ist die Vermeidung von RFOs (anscheinend senden sie eine Ungültigmachung, die sogar andere schmutzige Leitungen löscht, wenn sie mem erreichen). Sie können auch sichtbar out-of-order werden, so müssen sie nicht warten , bis nach einer früheren Cache-Miss (regular) Speicher Commits oder bis eine frühere Cache-Miss Last erhält Daten. dh die Art von Engpass, nach dem gefragt wird. Ist der Speicher außerhalb jedes Kerns in einem Multiprozessorsystem konzeptionell immer flach / einheitlich / synchron? .
Peter Cordes

1
@ LewisKelsey: Eine Speicherbestellmaschine, die gelöscht wird, kann alle Lasten nach einem UC-Speicher töten, die bei Bedarf nicht vorzeitig hätten durchgeführt werden dürfen. Abgesehen davon kommt die Festschreibungsreihenfolge erst ins Spiel, nachdem sich das Geschäft aus dem Back-End außerhalb der Bestellung zurückgezogen hat. Dies kann erst geschehen, nachdem die Speicheradresse uop ausgeführt wurde. An diesem Punkt kann der Speichertyp für die Adresse überprüft werden. Eine Geschäftsadresse uop überprüft den TLB, wenn er ausgeführt wird. Auf diese Weise können CPUs fehlerhafte Speicher erkennen, bevor sie in den Ruhestand gehen. Es kann nicht warten, bis der SB-Eintrag bereit ist, sich auf L1d festzulegen. An diesem Punkt ist die Ausführung vorbei.
Peter Cordes
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.