x86 では、命令をアトミックにするためにアライメントは必要ありません。lock cmpxchg
ただし、優れたパフォーマンスを得るにはアライメントが必要です。
これは当然のことです。下位互換性とは、14 年前のマニュアルで書かれたソフトウェアが現在のプロセッサでも実行できることを意味します。最新の CPU には、スプリット検出専用のパフォーマンス カウンターさえありますlock
。これは非常に高価だからです。(コアは、操作中に単一のキャッシュ ラインへの排他的アクセスを保持することはできません。従来のバス ロックのようなことを行う必要があります)。
Microsoft が整合要件を正確に文書化している理由は明確ではありません。RISC アーキテクチャをサポートするためには確かに必要ですが、マルチプロセッサ x86 での予測不可能な動作に関する特定の主張は、有効ではないかもしれません。(正確性の問題ではなく、予測不可能なパフォーマンスを意味する場合を除きます。)
486 より前のシステムにのみ適用するというあなたの推測はlock cmpxchg
正しいかもしれません。そこでは、純粋なロードまたは純粋なストアの周りにある種のロックが必要になる可能性のある別のメカニズムが必要になります。(また、486には、 586 Pentium で新しく追加された最新の( )cmpxchg
とは異なり、現在文書化されていないオペコード( 0f a7
)があることに注意してください。Windows はP5 Pentium 以降でのみ使用されていた可能性がありますが、私にはわかりません。)最近の x86 の奇妙さを暗示することなく、いくつかの x86。cmpxchg
0f b1
cmpxchg
インテル® 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
アトミック wrt です。コンテキスト スイッチであるため、シングルコア システムでのマルチスレッドに使用できます。
位置がずれていても、それはまだ原子的なものです。割り込み (完全に前または完全に後)、および他のデバイス (DMA など) によるメモリ読み取りのみがティアリングを確認できます。しかし、そのようなアクセスでは、ロードとストアの分離も見られる可能性があるため、古い Windows がシングルコア システムでより効率的な InterlockedCompareExchange のためにそれを使用したとしても、正確さのための調整は必要なく、パフォーマンスのみが必要です。これがハードウェア アクセスに使用できる場合、Windows はおそらくそれを行いません。
ライブラリ関数が とは別に純粋なロードを行う必要がある場合、lock cmpxchg
これは理にかなっているかもしれませんが、そうする必要はありません。(インライン化されていない場合、32 ビット バージョンはその引数をスタックからロードする必要がありますが、これはプライベートであり、共有変数へのアクセスではありません。)