質問

Intel 64およびIA-32アーキテクチャソフトウェア開発者のマニュアルによると、ロック信号のプレフィックスは「信号が主張されている間にプロセッサが共有メモリを排他的に使用することを保証します」。これは、バスまたはキャッシュロックの形式である可能性があります。

しかし、それが私がこの質問をしている理由です - このプレフィックスもメモリバリアを提供するかどうかは私には明らかではありません。

私はマルチプロセッサ環境でNASMを使用して発展しており、オプションの獲得および/またはリリースセマンティクスで原子操作を実装する必要があります。

それで、MFENCE、SFENCE、およびLFENCE命令を使用する必要がありますか、それともこれは冗長ですか?

役に立ちましたか?

解決

いいえ、手順を使用する必要はありません MFENCE, SFENCE and LFENCE との関係で LOCK プレフィックス。

MFENCE, SFENCE and LFENCE 命令は、すべてのCPUコアのメモリの可視性を保証します。インスタンス MOV 命令は使用できません LOCK プレフィックス、メモリの動きの結果がすべてのCPUコアに表示されることを確認するには、CPUキャッシュがRAMにフラッシュされ、フェンスの指示に到達することを確認する必要があります。

編集: Intelマニュアルからのロックされた原子操作の詳細:

ロックされた原子操作

32ビットIA-32プロセッサは、システムメモリの位置でロックされた原子動作をサポートしています。これらの操作は通常、2つ以上のプロセッサが同じフィールドまたはフラグを変更するために同時に試みることができる共有データ構造(セマフォ、セグメント記述子、システムセグメント、ページテーブルなど)を管理するために使用されます。プロセッサは、ロックされた原子動作を実行するために3つの相互依存メカニズムを使用します。

•保証された原子操作

•ロック#信号とロック命令のプレフィックスを使用して、バスロック

•キャッシュされたデータ構造(キャッシュロック)で原子操作を実行できることを保証するコヒーレンシープロトコルをキャッシュします。このメカニズムは、Pentium 4、Intel Xeon、およびP6ファミリープロセッサに存在します

これらのメカニズムは、次の方法で相互依存しています。特定の基本的なメモリトランザクション(システムメモリのバイトの読み取りや書き込みなど)は、常に原子的に処理されることが保証されています。つまり、開始すると、プロセッサは、別のプロセッサまたはバスエージェントがメモリの場所へのアクセスを許可する前に操作が完了することを保証します。また、プロセッサは、通常、原子的に処理する必要があるが、この方法で自動的に処理されない、選択されたメモリ操作(共有メモリの共有領域での読み取り装置操作など)を実行するためのバスロックをサポートします。頻繁に使用されるメモリの位置は、プロセッサのL1またはL2キャッシュでキャッシュされることが多いため、バスのロックを主張することなく、原子操作をプロセッサのキャッシュ内で行うことができます。ここでは、プロセッサのキャッシュコヒーレンシープロトコルは、同じメモリ位置をキャッシュしている他のプロセッサが適切に管理され、原子操作がキャッシュされたメモリ位置で実行されることを保証します。

他のヒント

いいえ。 IA32マニュアルから(第3A巻、第8.2章: メモリ順序):

読み取りまたは書き込みは、I/Oの指示で並べ替えることはできません、 ロックされた指示, 、またはシリアル化の指示。

したがって、ロックされた命令ではフェンスの命令は必要ありません。

intel_lock1.c(上記のURLで入手可能)がGCC 5または7のLinuxにコンパイルされている場合、問題はまだ発生します。 Mutex_Lockアセンブラーは次のようになりました:

# 74 "intel_lock1.c" 1
    LFENCE
    lock subl   $1, lck(%rip)
    rep nop
    SFENCE

だから、{l、s}フェンスをmfenceに置き換えようとしています。

ただし、2つのスレッドが同じ-1 *LCK値になる方法がまだよくわかりません。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top