31

DSB、DMB、およびISBは、命令の並べ替えを防ぐための障壁であることを理解しています。それぞれについて非常に良い説明をたくさん見つけることができますが、私がそれらを使用しなければならない場合を想像するのはかなり難しいです。

また、オープンソースコードからは、それらの障壁が時々見られますが、なぜそれらが使用されているのかを理解するのは非常に困難です。ほんの一例として、Linuxカーネル3.7のtcp_rcv_synsent_state_process関数には、次のような行があります。

    if (unlikely(po->origdev))
            sll->sll_ifindex = orig_dev->ifindex;
    else
            sll->sll_ifindex = dev->ifindex;

    smp_mb();

    if (po->tp_version <= TPACKET_V2)
            __packet_set_status(po, h.raw, status);

ここで、smp_mb()は基本的にDMBです。実際の例をいくつか教えてください。それは障壁についてもっと理解するのに役立つでしょう。

4

3 に答える 3

47

申し訳ありませんが、あなたが求めているような簡単な例を示すつもりはありません。すでにLinuxソースコードを調べているので、周りにはたくさんのソースコードがあり、それらは役に立たないようです。恥ずべきことではありません-すべての正気の人は、少なくとも最初はメモリアクセスの順序の問題に混乱しています:)

あなたが主にアプリケーション開発者である場合、それについてあまり心配する必要がない可能性があります-使用する同時実行フレームワークが何であれ、それを解決します。

あなたが主にデバイスドライバーの開発者である場合、例を見つけるのはかなり簡単です-他のアクセスが実行される前に、以前のアクセスに影響があった(割り込みソースをクリアした、DMA記述子を書き込んだ)コードに依存関係があるときはいつでも(割り込みを再度有効にし、DMAトランザクションを開始します)。

並行性フレームワークの開発(またはデバッグ)の過程にある場合は、おそらくトピックについてもう少し読む必要がありますが、あなたの質問は、差し迫った必要性ではなく、表面的な好奇心を示唆していますか?並行性フレームワークによって提供されるプリミティブに基づいていない、スレッド間でデータを渡すための独自のメソッドを開発している場合、それはすべての目的と目的のために並行性フレームワークです。

Paul McKenneyは、メモリバリアの必要性と、それらがプロセッサに実際にどのような影響を与えるかについて、優れた論文を書きました。メモリバリア:ソフトウェアハッカーのハードウェアビュー

それが少しハードコアすぎる場合は、もう少し軽量で、ARM固有のビューで終わる3部構成のブログシリーズを作成しました。最初の部分は、メモリアクセスの順序付けです-はじめに

しかし、特にARMアーキテクチャの場合、特にARMアーキテクチャの場合は、Barrier Litmus TestsandCookbookよりもはるかに悪い結果になる可能性があります。

非常に軽いプログラマーの見解であり、完全にアーキテクチャ的に正しいバージョンではありません。

  • DMB-メモリアクセスが別のメモリアクセスに関して順序付けを必要とするときはいつでも。
  • DSB-プログラムの実行が進む前にメモリアクセスを完了する必要があるときはいつでも。
  • ISB-メモリマップの更新後や実行するコードの記述後など、プログラムの特定のポイントの後で命令フェッチを明示的に実行する必要がある場合は常に。(実際には、これは「この時点でプリフェッチされた命令を破棄する」ことを意味します。)
于 2013-03-19T07:39:43.623 に答える
9

通常、メモリアクセスが特定の順序で発生することを確認する必要がある場合は、メモリバリアを使用する必要があります。これはいくつかの理由で必要になる場合があります。通常、2つ以上のプロセス/スレッドまたはハードウェアコンポーネントが同じメモリ構造にアクセスする場合に必要であり、一貫性を保つ必要があります。

DMA転送で非常に頻繁に使用されます。単純なDMA制御構造は次のようになります。

struct dma_control {
  u32 owner;
  void * data;
  u32 len;
};

所有者は通常、OWNER_CPUやOWNER_HARDWAREのようなものに設定され、2人の参加者のどちらが構造を操作できるかを示します。

これを変更するコードは通常このようになります

dma->data = data;
dma->len  = length;
smp_mb();
dma->owner = OWNER_HARDWARE;

したがって、データlenは、所有権がDMAハードウェアに転送される前に常に設定されます。そうしないと、CPUがメモリアクセスを並べ替えたために、更新されなかったポインタや長さなど、エンジンが古いデータを取得する可能性があります。

異なるコアで実行されているプロセスまたはスレッドについても同じことが言えます。同様の方法で通信できます。

于 2013-03-19T07:26:06.190 に答える
3

バリア要件の簡単な例の1つは、スピンロックです。コンペアアンドスワップ(またはARMではLDREX / STREX)を使用して、バリアなしでスピンロックを実装する場合、プロセッサはメモリから値を投機的にロードし、計算された値をメモリに遅延保存することができます。命令ストリーム内のロード/ストアの順序で。

特にDMBは、DMB周辺でのメモリアクセスの並べ替えを防ぎます。DMBがないと、スピンロックが解放された後、プロセッサはスピンロックによって保護されているメモリにストアを並べ替えることができます。または、プロセッサは、スピンロックが実際にロックされる前、または別のコンテキストによってロックされている間に、スピンロックによって保護されたメモリを読み取ることができます。

unixsmurfはすでにそれを指摘していますが、バリアリトマス試験とクックブックについても指摘します。バリアを使用する場所と理由のかなり良い例がいくつかあります。

于 2013-07-31T06:31:16.713 に答える