7

次のように、カーネル ソース Documentation/memory-barriers.txt に図があります。

    CPU 1                   CPU 2
    ======================= =======================
            { B = 7; X = 9; Y = 8; C = &Y }
    STORE A = 1
    STORE B = 2
    <write barrier>
    STORE C = &B            LOAD X
    STORE D = 4             LOAD C (gets &B)
                            LOAD *C (reads B)

介入がなければ、CPU 1 によって発行された書き込みバリアにもかかわらず、CPU 2 は CPU 1 のイベントを事実上ランダムな順序で認識する可能性があります。

    +-------+       :      :                :       :
    |       |       +------+                +-------+  | Sequence of update
    |       |------>| B=2  |-----       --->| Y->8  |  | of perception on
    |       |  :    +------+     \          +-------+  | CPU 2
    | CPU 1 |  :    | A=1  |      \     --->| C->&Y |  V
    |       |       +------+       |        +-------+
    |       |   wwwwwwwwwwwwwwww   |        :       :
    |       |       +------+       |        :       :
    |       |  :    | C=&B |---    |        :       :       +-------+
    |       |  :    +------+   \   |        +-------+       |       |
    |       |------>| D=4  |    ----------->| C->&B |------>|       |
    |       |       +------+       |        +-------+       |       |
    +-------+       :      :       |        :       :       |       |
                                   |        :       :       |       |
                                   |        :       :       | CPU 2 |
                                   |        +-------+       |       |
        Apparently incorrect --->  |        | B->7  |------>|       |
        perception of B (!)        |        +-------+       |       |
                                   |        :       :       |       |
                                   |        +-------+       |       |
        The load of X holds --->    \       | X->9  |------>|       |
        up the maintenance           \      +-------+       |       |
        of coherence of B             ----->| B->2  |       +-------+
                                            +-------+
                                            :       :

書き込みバリアがあるため、わかりません。C = &B が実行されたときにストアが有効になる必要があります。つまり、Ce B が 2 に等しくなったときです。 C は &B ですが、なぜ B を 7 と認識するのでしょうか。私は本当に混乱しています。

4

2 に答える 2

8

「メモリバリアについて想定されていないことは何ですか?」というタイトルのドキュメントのセクションから:

メモリ バリアの前に指定されたメモリ アクセスのいずれかが、メモリ バリア命令の完了によって完了するという保証はありません。バリアは、適切なタイプのアクセスが通過できない CPU のアクセス キューに線を引くと見なすことができます。

最初の CPU が一致するメモリ バリアを使用しない限り、2 番目の CPU がメモリ バリアを使用している場合でも、CPU が 2 番目の CPU のアクセスから正しい順序で影響を受けるという保証はありません(「SMP バリアのペアリング」のサブセクションを参照)。 )。

メモリ バリアが (もちろん非常に単純化された方法で) 行うことは、コンパイラも CPU 内ハードウェアも、バリアを越えてロード (またはストア) 操作を巧妙に並べ替えようとしないことと、CPU がメモリへの変更を正しく認識することです。システムの他の部分によって作成されたメモリ。これは、ロックしているものにアクセスする前にロックをロックするなど、ロード (またはストア) に追加の意味がある場合に必要です。この場合、コンパイラ/CPU に順序を変更してアクセスを効率化させることは、プログラムの正しい動作にとって危険です。

このドキュメントを読むときは、次の 2 つの点に注意する必要があります。

  1. ロードとは、メモリ (またはキャッシュ) から CPU レジスタに値を送信することを意味します。
  2. CPU がキャッシュを共有している (またはまったくキャッシュを持っていない) 場合を除き、CPU のキャッシュ システムが一時的に同期されない可能性があります。

事実 2 は、ある CPU が別の CPU とは異なる方法でデータを認識できる理由の 1 つです。キャッシュ システムは、一般的なケースで優れたパフォーマンスと一貫性を提供するように設計されていますが、ドキュメントに示されているような特定のケースでは何らかの支援が必要になる場合があります。

一般に、ドキュメントが示唆するように、複数の CPU を含むシステムのバリアは、システムが両方 (または参加しているすべて) の CPU の認識を同期させるようにペアリングする必要があります。1 つの CPU がロードまたはストアを完了し、メイン メモリが更新されたが、新しいデータがまだ 2 番目の CPU のキャッシュに転送されておらず、両方の CPU 間の一貫性が失われている状況を想像してみてください。

これが役立つことを願っています。これを念頭に置いて、memory-barriers.txt、特に「CPU キャッシュの影響」というタイトルのセクションをもう一度読むことをお勧めします。

于 2013-06-07T13:10:49.450 に答える
8

重要な欠落点は、シーケンスに対する誤った仮定です。

LOAD C (gets &B)
LOAD *C (reads B)

最初のロードは 2 番目のロードよりも前に行う必要があります。弱い順序付けのアーキテクチャは、次のことが「あたかも」発生したかのように動作する可能性があります。

LOAD B (reads B)  
LOAD C (reads &B)
if( C!=&B ) 
    LOAD *C
else
    Congratulate self on having already loaded *C

投機的な「LOAD B」が発生する可能性があります。たとえば、B が以前に関心のある他の変数と同じキャッシュ ライン上にあったか、ハードウェア プリフェッチがそれを取得したためです。

于 2013-06-07T22:11:42.947 に答える