web-dev-qa-db-ja.com

x86 / x86_64プロセッサでLFENCE命令を使用することには意味がありますか?

多くの場合、インターネットに私はすなわち、それが原因でLFENCE = MFENCE + SFENCE = MFENCE + SFENCE = LFENCE、その代わりに、私たちは絶対にSFENCE使用する無痛できNOP、何もしない、プロセッサは、x86でそのSFENCEは意味がありません見つけます。

しかし、LFENCEが意味をなさない場合は、x86/x86_64で順次整合性を確保するために4つの方法があるのはなぜですか。

  1. LOAD(フェンスなし)およびSTORE + MFENCE
  2. LOAD(フェンスなし)および_LOCK XCHG_
  3. MFENCE + LOADおよびSTORE(フェンスなし)
  4. _LOCK XADD_(0)およびSTORE(フェンスなし)

ここから取得: http://www.cl.cam.ac.uk/~pes20/cpp/cpp0xmappings.html

下部の34ページの「ハーブサッター」のパフォーマンス: https://skydrive.live.com/view.aspx?resid=4E86B0CF20EF15AD!24884&app=WordPdf&wdo=2&authkey=!AMtj_EflYn2507c

LFENCEが何もしなかった場合、アプローチ(3)の意味はSFENCE + LOAD and STORE (without fence)になりますが、SFENCEの前にLOADを実行しても意味がありません。つまり、LFENCEが何もしない場合、アプローチ(3)は意味がありません。

プロセッサx86/x86_64でLFENCEは意味のある命令ですか?

回答:

1。LFENCEは、以下の承認された回答に記載されている場合に必要です。

2。アプローチ(3)は、個別にではなく、前のコマンドと組み合わせて表示する必要があります。たとえば、アプローチ(3):

_MFENCE
MOV reg, [addr1]  // LOAD-1
MOV [addr2], reg  //STORE-1

MFENCE
MOV reg, [addr1]  // LOAD-2
MOV [addr2], reg  //STORE-2
_

アプローチ(3)のコードは次のように書き換えることができます。

_SFENCE
MOV reg, [addr1]  // LOAD-1
MOV [addr2], reg  //STORE-1

SFENCE
MOV reg, [addr1]  // LOAD-2
MOV [addr2], reg  //STORE-2
_

そして、ここでSFENCEは、STORE-1とLOAD-2の順序変更を防ぐのに意味があります。このため、STORE-1コマンドの後、SFENCEはStore-Bufferをフラッシュします。

43
Alex

結論(TL; DR):LFENCEだけでは、実際にはメモリの順序付けには役に立たないようですが、SFENCEMFENCEの代わりに使用することはできません。質問の「算術」ロジックは適用されません。


インテルのソフトウェア開発者向けマニュアル、ボリューム 、セクション8.2.2(2014年9月の版325384-052US)からの抜粋です。これは 別の回答 で使用したものと同じです。

  • 読み取りは他の読み取りと並べ替えられません。
  • 書き込みは、古い読み取りでは並べ替えられません。
  • メモリへの書き込みは、次の例外を除いて、他の書き込みと並べ替えられません。
    • cLFLUSH命令で実行された書き込み。
    • 非時間移動命令(MOVNTI、MOVNTQ、MOVNTDQ、MOVNTPS、およびMOVNTPD)で実行されるストリーミングストア(書き込み)。そして
    • 文字列操作(セクション8.2.4.1を参照)。
  • 読み取りは、異なる場所への古い書き込みでは並べ替えられますが、同じ場所への古い書き込みでは並べ替えられません。
  • 読み取りまたは書き込みは、I/O命令、ロックされた命令、またはシリアル化命令で並べ替えることはできません。
  • 読み取りは、以前のLFENCEおよびMFENCE命令を渡すことはできません。
  • 以前のLFENCE、SFENCE、およびMFENCE命令を書き込むことはできません。
  • LFENCE命令は以前の読み取りを渡すことができません。
  • SFENCE命令は以前の書き込みを渡すことができません。
  • MFENCE命令は、以前の読み取りまたは書き込みを渡すことができません。

ここからは、次のようになります。

  • MFENCEは、非一時的かどうかにかかわらず、すべてのメモリタイプのすべての操作に対する完全なメモリフェンスです。
  • SFENCEは書き込みの並べ替えを防止するだけであり(他の用語では、StoreStoreバリアです)、非一時的なストアや例外としてリストされている他の命令と一緒にのみ役立ちます。
  • LFENCEは、後続の読み取りと書き込みを伴う読み取りの並べ替えを防ぎます(つまり、LoadLoadバリアとLoadStoreバリアを組み合わせます)。ただし、最初の2つの箇条書きは、LoadLoadバリアとLoadStoreバリアが常に配置されていることを示しており、例外はありません。したがって、LFENCEだけではメモリの順序付けには役に立ちません。

最後の主張を裏付けるために、Intelのマニュアルの3巻すべてでLFENCEが言及されているすべての場所を調べましたが、LFENCEがメモリの一貫性のために必要であると言うことはありませんでした。 MOVNTDQA-現時点で唯一の非時間的ロード命令-MFENCEについては言及していますが、LFENCEについては言及していません。


更新:以下の当て推量に対する正しい答えについては、 なぜですか(そうでないのですか?)SFENCE + LFENCEはMFENCEと同等ですか? の回答を参照してください

MFENCEが他の2つのフェンスの「合計」に等しいかどうかは、難しい問題です。一見すると、3つのフェンス命令のうち、MFENCEのみがStoreLoadバリアを提供します。つまり、以前の書き込みでの読み取りの並べ替えを防止します。しかし、正しい答えは上記のルール以上を知る必要があります。つまり、すべてのフェンス命令が互いに関して順序付けられていることが重要です。これはSFENCE LFENCEシーケンスは、個々のエフェクトの単なる和集合よりも強力です。このシーケンスは、StoreLoadの並べ替えも防止します(ロードがLFENCEを渡すことができず、SFENCEを渡すことができず、ストアを渡すことができないため)。完全なメモリフェンス(ただし、下の注(*)も参照)。ただし、ここでは順序が重要であり、LFENCE SFENCEシーケンスは同じ相乗効果を持ちません。

ただし、MFENCE ~ SFENCE LFENCEおよびLFENCE ~ NOP、という意味ではありませんMFENCE ~ SFENCE。ここでは、算術規則がここでは適用されないことを強調するために、等価(〜)と等価ではない(=)を意図的に使用しています。 SFENCEとそれに続くLFENCEの相互影響により違いが生じます。ロードが相互に並べ替えられない場合でも、LFENCEを使用したロードの並べ替えを防ぐにはSFENCEが必要です。

(*)MFENCEは他の2つのフェンスの組み合わせよりも強力であると言っても正しいかもしれません。特に、Intelのマニュアルの第2巻にあるCLFLUSH命令への注記では、「CLFLUSHMFENCE命令によってのみ順序付けられます。順序付けは保証されません。その他のフェンシングまたはシリアル化命令、または別のCLFLUSH命令による。」

(更新、clflushは強い順序付けとして定義されるようになりました(通常のストアのように、後でブロックする場合のみmfenceが必要ですloads )、ただしclflushoptは弱い順序付けですが、sfenceでフェンスできます。)

31
Alexey Kukanov

次のシナリオを検討してください-これは、理論的なロードの実行が理論的にシーケンシャルな一貫性を損なう可能性がある重大なケースです

最初は[x] = [y] = 0

CPU0:                              CPU1: 
store [x]<--1                      store [y]<--1
load  r1<--[y]                     load r2<--[x]

X86では、以前のストアで別のアドレスにロードを並べ替えることができるため、どちらのロードも0を返す場合があります。各ストアの後に単独でフェンスを追加しても、同じコンテキスト内での並べ替えが妨げられるだけではありません。ただし、ストアがリタイア後にディスパッチされるため、ストアが実行および監視される前に、両方のフェンスと両方のロードをコミットできます。

一方、mfenceは、ストアを強制的に実行し、その後ロードの実行を許可するため、更新されたデータが表示されます少なくとも1つのコンテキスト。

sfencesと同様に、コメントで指摘されているように、理論的には、その上にロードが並べ替えられないようにするほど強力ではないため、まだ古くなっている可能性がありますデータ。これは、メモリの公式の順序付け規則が適用される限りは当てはまりますが、x86 uarchの現在の実装により、多少強化されると思います(将来的にはそうすることを約束しませんが)。 この説明 によると:

強力なx86順序モデルのため、ロードバッファーはコヒーレンシトラフィックによってスヌーピングされます。リモートストアは、キャッシュラインの他のすべてのコピーを無効にする必要があります。キャッシュラインがロードによって読み取られ、リモートストアによって無効化された場合、無効なデータを読み取る可能性があるため、ロードをキャンセルする必要があります。 x86メモリモデルでは、ストアバッファをスヌーピングする必要はありません。

したがって、マシンでまだコミットされていない負荷は、他のコアからのストアによってスヌープできるはずです。これにより、での負荷の観測時間commitポイントであり、executionポイントではありません(実際に順序が狂っており、以前に実行された可能性があります) )。コミットは順番に行われるため、前の指示の後に負荷を監視する必要があります。上記のコメントで述べたように、フェンスは無用に一貫性を維持できるため、フェンスはほとんど役に立ちません。これは主に推測であり、x86でlfencesは無意味であるという一般的な概念を説明しようとします-それがどこで発生したのか完全に定かではありません。

上記はすべて、WB memタイプのコースにのみ適用されます

8
Leeor