Bricht das flüchtige Qualifikationsmerkmal das Zwischenspeichern für diesen Speicher ab?

8

In diesem Artikel: Ссылка sagt, dass wir keine Optimierung für volatile vornehmen können, auch nicht wie (wo: volatile int& v = *(address); ):

%Vor%

kann nicht dafür optimiert werden:

%Vor%

Dies ist nicht möglich, da zwischen% 1 und 2% v -Wert von Hardware-Gerät geändert werden kann (nicht CPU, wo Cache-Kohärenz nicht funktioniert: Netzwerkadapter, GPU, FPGA, usw. ..) (sequentila / concurrency), die diesem Speicherort zugeordnet sind. Aber es ist nur dann sinnvoll, wenn v nicht im CPU-Cache L1 / 2/3 zwischengespeichert werden kann, weil für gewöhnliche (nicht volatile ) Variable zwischen 1. und 2. Zeile zu wenig Zeit ist und wahrscheinlich im Cache ausgelöst wird .

Gewährleistet das volatile -Qualifier kein Caching für diesen Speicherort?

ANTWORT:

  1. Nein, volatile garantiert kein Caching für diesen Speicherort, und in C / C ++ - Standards oder Handbuch des Compilers .
  2. Bei der Verwendung der Speicherbereichszuordnung wird der Speicher, der vom Gerätespeicher zum CPU-Speicher zugeordnet wurde, bereits als WC gekennzeichnet (write combining) anstelle von WB, wodurch das Caching abgebrochen wird. Und keine Cachespülung durchführen .
  3. Umgekehrt schnüffelt dann, wenn der CPU-Speicher dem Gerätespeicher zugeordnet ist, der Controller PCIE, der sich auf dem CPU-Kristall befindet, nach Daten, die von diesem Gerät durch DMA gehen, und aktualisiert (ungültig macht) den CPU-Cache L3 . In diesem Fall, wenn der ausführbare Code auf dem Gerät, das volatile verwendet, versucht, dieselben zwei Zeilen auszuführen, löscht es auch den Cache-Speicher des Geräts (z. B. in der Cache-GPU-L2). Und muss keine GPU-Cache-Spülung durchführen und muss keine CPU-Cache-Spülung durchführen . Auch für die CPU muss möglicherweise std::atomic_thread_fence(std::memory_order_seq_cst); verwendet werden, wenn L3-Cache (LLC) -Kohärenz mit DMA über PCIE, aber L1 / L2 ist nicht . Und für nVidia CUDA können wir verwenden: void __threadfence_system();
  4. Wir müssen den DMA-Controller-Cache leeren , wenn wir nicht ausgerichtete Daten senden: (WDK: KeFlushIoBuffers(), FlushAdapterBuffers() )
  5. Außerdem können wir jeden Speicherbereich als nicht zwischengespeichert markieren, wie WC, der von Ihnen selbst über die MTRR-Register markiert ist.
Alex 31.08.2013, 17:16
quelle

1 Antwort

6

volatile stellt sicher, dass die Variable nicht im CPU-Register "zwischengespeichert" wird. Der CPU-Cache ist für den Programmierer transparent, und wenn eine andere CPU in den Speicher schreibt, der durch den Cache einer anderen CPU zugeordnet wird, wird der Cache der zweiten CPU ungültig gemacht. Daher wird der Wert beim nächsten Zugriff erneut aus dem Speicher geladen.

Etwas über Cache-Kohärenz

Wie bei den externen Speicherschreibvorgängen (über DMA oder einen anderen CPU-unabhängigen Kanal) müssen Sie den Cache möglicherweise manuell leeren (siehe diese SO Frage)

C Standard §6.7.3 7:

  

Was einen Zugang zu einem Objekt darstellt, das   hat einen flüchtigen qualifizierten Typ ist Implementierung definiert.

    
Erbureth 31.08.2013, 17:21
quelle

Tags und Links