アトミックx86命令のアライメント要件
-
06-07-2019 - |
質問
Microsoftは InterlockedCompareExchange を提供していますアトミックな比較とスワップ操作を実行するためのcode>
関数。 _InterlockedCompareExchange
組み込み。
x86では、これらは cmpxchg
命令を使用して実装されます。
ただし、これら3つのアプローチに関するドキュメントを読むと、アライメント要件に同意していないようです。
Intelのリファレンスマニュアルには、アライメントについて何も記載されていません(それ以外は if アライメントチェックが有効で、アライメントされていないメモリ参照が行われた場合、例外が生成されます)
lock
プレフィックスも検索しました。
LOCKプレフィックスの整合性は、メモリフィールドの配置の影響を受けません 。
(強調鉱山)
したがって、Intelはアライメントは無関係であると言っているようです。操作は何であれアトミックになります。
_InterlockedCompareExchange
の組み込みドキュメントにもアライメントについては何も記載されていませんが、 InterlockedCompareExchange
function には次のように記載されています
この関数のパラメーターは、32ビット境界に揃える必要があります。そうしないと、マルチプロセッサx86システムおよび非x86システムで関数が予期しない動作をします。
では、何が得られますか?
cmpxchg
命令が使用できない486以前のCPUでも機能が動作することを確認するための InterlockedCompareExchange
のアライメント要件はありますか?
これはおそらく上記の情報に基づいているようですが、それに頼る前に確認したいと思います。 :)
または、ISAは原子性を保証するためにアライメントを必要としますが、Intelのリファレンスマニュアルで間違った場所を探しているだけですか?
解決
引用元のPDF は1999年のもので、明らかに古くなっています。
最新のIntelドキュメント、特に Volume-3A は異なる話をします。
たとえば、Core-i7プロセッサでは、データがキャッシュラインにまたがらないようにする必要があります。そうしないと、操作がアトミックであることが保証されません。
ボリューム3A、システムプログラミング、x86 / x64の場合Intelは次のように明確に述べています。
8.1.1保証されたアトミック操作
Intel486プロセッサー(およびそれ以降の新しいプロセッサー)は、以下を保証します。 基本的なメモリ操作は常にアトミックに実行されます:
- バイトの読み取りまたは書き込み
- 16ビット境界に整列した単語の読み取りまたは書き込み
- 32ビット境界で整列されたダブルワードの読み取りまたは書き込み
Pentiumプロセッサ(およびそれ以降の新しいプロセッサ)は、以下を保証します。 追加のメモリ操作は常にアトミックに実行されます:
- 64ビット境界で整列したクワッドワードの読み取りまたは書き込み
- 32ビットデータバスに収まるキャッシュされていないメモリ位置への16ビットアクセス
P6ファミリプロセッサ(およびそれ以降の新しいプロセッサ)は、以下を保証します。 追加のメモリ操作は常にアトミックに実行されます:
- キャッシュ内に収まるキャッシュメモリへの16ビット、32ビット、64ビットの非境界整列アクセス 行
キャッシュラインとページ境界に分割されているキャッシュ可能なメモリへのアクセス Intel Core 2 Duo、Intel®によるアトミック性の保証はありません。 Atom™、Intel Core Duo、Pentium M、Pentium 4、Intel Xeon、P6ファミリ、Pentium、およびIntel486プロセッサ。 Intel Core 2 Duo、Intel Atom、Intel Core Duo、Pentium M、Pentium 4、Intel Xeon、 およびP6ファミリプロセッサは、外部メモリを許可するバス制御信号を提供します 分割アクセスをアトミックにするサブシステム。ただし、非境界整列データアクセスは プロセッサのパフォーマンスに深刻な影響を与えるため、避けるべきです
他のヒント
x86では、 cmpxchg
命令の位置合わせは必要ありません。ただし、パフォーマンスのために位置合わせをお勧めします。これは驚くべきことではありません。下位互換性とは、14年前のマニュアルで作成されたソフトウェアが現在のプロセッサで引き続き実行されることを意味します。
Microsoftがアラインメントを正確に必要とする理由は、ドキュメントから明らかではありません。パフォーマンスのため、またはRISCアーキテクチャをサポートするため、あるいはその両方のための可能性があります。
Intel® 64およびIA-32アーキテクチャソフトウェア開発者向けマニュアル
ボリューム3(3A):システムプログラミングガイド
2013年1月8.1.2.2ソフトウェア制御バスロック
LOCKセマンティクスを明示的に強制するために、ソフトウェアは、メモリの場所を変更するために使用される場合、次の命令でLOCKプレフィックスを使用できます。 [...]
•交換指示(XADD、CMPXCHG、およびCMPXCHG8B)。
• XCHG命令では、LOCKプレフィックスが自動的に想定されます。
• [...][...]バスロックの整合性は、 メモリフィールド。 LOCKセマンティクスは、バスサイクルと同じ数だけ続きます 必要に応じて、オペランド全体を更新します。ただし、お勧めです ロックされたアクセスは、より良いために自然な境界で整列される システムパフォーマンス:
• 8ビットアクセスのすべての境界(ロックまたはその他)。
•ロックされたワードアクセスの16ビット境界。
•ロックされたダブルワードアクセスの32ビット境界。
•ロックされたクワッドワードアクセスの64ビット境界。
このSOの質問を参照してください:自然なアライメントはパフォーマンスにとって重要であり、 x64アーキテクチャ(PRE-x86システムだけでなく、POST-x86システムも同様です。x64はまだニッチなケースかもしれませんが、結局人気が高まっています;-); Microsoftが必要に応じて文書化する理由となる場合があります(MSがアライメントチェックを有効にしてアライメントの問題を強制することを決定したかどうかに関するドキュメントを見つけるのは困難です-Windowsのバージョンによって異なる場合があります。あるバージョンのWindowsでは、他のバージョンで強制しなくても強制することができます。
MicrosoftのInterlocked APIは、ia64にも適用されました(まだ存在していました)。 ia64にはロックプレフィックスはなく、cmpxchg.acq命令とcmpxchg.rel命令(またはfetchaddと他の類似の怪物)のみがあり、これらを正しく思い出す場合はすべてアライメントが必要でした。