アトミック x86 命令のアラインメント要件と MS の InterlockedCompareExchange ドキュメントの違いは何ですか? 質問する

アトミック x86 命令のアラインメント要件と MS の InterlockedCompareExchange ドキュメントの違いは何ですか? 質問する

マイクロソフトはInterlockedCompareExchangeアトミックな比較とスワップ操作を実行する関数。また、_InterlockedCompareExchange 本質的な

x86 では、これらはlock cmpxchg命令を使用して実装されます。

しかし、これら 3 つのアプローチに関するドキュメントを読んでみると、アライメント要件については合意されていないようです。

インテルの参考マニュアル配置については何も言及していない(それ以外はもしアライメントチェックが有効になっていて、アライメントされていないメモリ参照が行われると、例外が生成されます)

私はまた、接頭辞を調べましたlock。具体的には、

LOCKプレフィックスの整合性はないメモリ フィールドの配置によって影響を受けます。

(強調は筆者による)

つまり、Intel は、アライメントは無関係であると言っているようです。操作はどのような場合でもアトミックになります。

内部_InterlockedCompareExchangeドキュメントにもアライメントについては何も書かれていないが、InterlockedCompareExchange 関数と述べています

この関数のパラメータは 32 ビット境界に揃える必要があります。そうしないと、この関数はマルチプロセッサ x86 システムおよび x86 以外のシステムで予期しない動作をします。

それで、何が起こっているのでしょうか?命令が利用できないInterlockedCompareExchange486 以前の CPU でも関数が確実に動作するように、アラインメント要件を設定しているのcmpxchgでしょうか? 上記の情報に基づくと、その可能性が高いと思われますが、それに頼る前に確認しておきたいと思います。:)

それとも、アトミック性を保証するために ISA によってアライメントが要求されており、私が Intel のリファレンス マニュアルで間違った場所を調べているだけなのでしょうか?

ベストアンサー1

x86はないlock cmpxchg命令をアトミックにするにはアライメントが必要です。ただし、良好なパフォーマンスを得るにはアライメントが不可欠です。

これは驚くことではありません。下位互換性とは、14 年前のマニュアルで作成されたソフトウェアが、今日のプロセッサでも実行できることを意味します。現代の CPU には、スプリットlock検出は非常に高価なため、専用のパフォーマンス カウンターさえあります。(コアは、操作中は単一のキャッシュ ラインへの排他的アクセスを保持するだけでは不十分で、従来のバス ロックのような処理を実行する必要があります)。

Microsoft がなぜアライメント要件を文書化しているのかは明確ではありません。RISC アーキテクチャをサポートするためには確かに必要ですが、マルチプロセッサ x86 での予測不可能な動作という具体的な主張は有効ではない可能性があります (正確性の問題ではなく、予測不可能なパフォーマンスを意味している場合を除く)。

486以前のシステムにのみ適用されるというあなたの推測はlock cmpxchg正しいかもしれません。そこでは、純粋なロードや純粋なストアの周りに何らかのロックを必要とするような異なるメカニズムが必要だったでしょう。(また、486にはcmpxchg異なる、現在文書化されていないオペコード0f a7) からモダンなcmpxchg0f b1これは 586 Pentium で新しく追加された機能です。Windows ではcmpxchgP5 Pentium 以降でのみ使用されていた可能性がありますが、私にはわかりません。) これにより、一部の x86 での異常が説明される可能性がありますが、最新の x86 での異常を意味するものではありません。

Intel® 64 および IA-32 アーキテクチャ ソフトウェア デベロッパーズ マニュアル
第 3 巻 (3A): システム プログラミング ガイド
2013 年 1 月

8.1.2.2 ソフトウェア制御のバスロック

LOCK セマンティクスを明示的に強制するには、ソフトウェアでメモリ位置を変更するときに、次の命令に LOCK プレフィックスを使用できます。 [...]

• 交換命令 (XADD、CMPXCHG、CMPXCHG8B)。
• XCHG 命令では、LOCK プレフィックスが自動的に想定されます。
• [...]

[...] バス ロックの整合性は、メモリ フィールドのアラインメントの影響を受けません。 LOCK セマンティクスは、オペランド全体を更新するために必要な数のバス サイクルで適用されます。 ただし、システム パフォーマンスを向上させるには、ロックされたアクセスを自然な境界に合わせることをお勧めします。

• 8 ビット アクセスの任意の境界 (ロックされているかどうかに関係なく)。
• ロックされたワード アクセスの 16 ビット境界。
• ロックされたダブルワード アクセスの 32 ビット境界。
• ロックされたクワッドワード アクセスの 64 ビット境界。


楽しい事実:cmpxchg それなしプレフィックスlockはコンテキストスイッチに関して依然としてアトミックであるなので、シングルコアシステムでのマルチスレッドに使用できます。

ミスアラインメントであっても、割り込みに関してはアトミックであり (完全に前か完全に後)、ティアリングが発生する可能性があるのは他のデバイス (DMA など) によるメモリ読み取りのみです。ただし、このようなアクセスではロードとストアが分離される可能性があるため、古い Windows がシングルコア システムでより効率的な InterlockedCompareExchange にこれを使用していたとしても、正確性のためにアラインメントは必要なく、パフォーマンスのみが必要です。これがハードウェア アクセスに使用できる場合、Windows はおそらくこれを実行しないでしょう。

ライブラリ関数がlock cmpxchgこれとは別に純粋なロードを実行する必要がある場合は意味があるかもしれませんが、そうする必要はありません。(インライン化されていない場合、32 ビット バージョンはスタックから引数をロードする必要がありますが、これはプライベートであり、共有変数へのアクセスではありません。)

おすすめ記事