どの CPU アーキテクチャがアトミック プリミティブの比較とスワップをサポートしているか知りたいですか?
10 に答える
Powerpc には、より強力なプリミティブがあります: "lwarx" と "stwcx"
lwarx はメモリから値をロードしますが、その場所は覚えています。その場所に触れる他のスレッドまたは CPU は、条件付きストア命令である「stwcx」を失敗させます。
したがって、lwarx /stwcx コンボを使用すると、アトミック インクリメント/デクリメント、比較とスワップ、および「アトミック インクリメント循環バッファー インデックス」などのより強力なアトミック操作を実装できます。
この質問に答える別の簡単な方法は、コンペアアンドスワップ(またはロードリンク/ストア条件付き)をサポートしていないマルチプロセッサプラットフォームを一覧表示することです。
私が知っているのはPARISCだけです。これには、アトミックなクリアワード命令しかありません。これは、ミューテックスを構築するために使用できます(ただし、16バイト境界でワードを整列させる場合)。このアーキテクチャにはCASはありません(x86、ia64、ppc、sparc、mips、s390などとは異なります)。
cmpxchg の x86/x64 で「ロック」プレフィックスが必要かどうかについて、何人かの人々がコメント/質問しました。マルチコア マシンの場合、答えはイエスです。この命令は、ロックのないシングル コア マシンでは完全にアトミックです。
このことを深く研究してからしばらく経ちましたが、命令は技術的に再起動可能であることを覚えているようです。割り込み処理の遅延を避けるために、飛行中に命令を中止することができます (副作用がまだない場合)。長いです。
ARMv6 アーキテクチャ以降、ARM には、アトミックな比較交換操作を実装するために使用できる LDREX/STREX 命令があります。
Intel x86 はこれをサポートしています。IBM は、Solaris to Linux Porting Guideで次の例を示しています。
bool_t My_CompareAndSwap(IN int *ptr, IN int old, IN int new)
{
unsigned char ret;
/* Note that sete sets a 'byte' not the word */
__asm__ __volatile__ (
" lock\n"
" cmpxchgl %2,%1\n"
" sete %0\n"
: "=q" (ret), "=m" (*ptr)
: "r" (new), "m" (*ptr), "a" (old)
: "memory");
return ret;
}
リストを完成させるために、MIPS には Load Linked (ll) 命令と Store Conditional (sc) 命令があり、メモリから値をロードし、他の CPU がその場所にアクセスしていない場合は後で条件付きで格納します。これらの命令を使用して、スワップ、インクリメント、およびその他の操作を実行できることは事実です。ただし、欠点は、多数の CPU が非常に頻繁にロックを実行すると、ライブロックが発生することです。条件付きストアは頻繁に失敗し、再試行するために別のループが必要になり、失敗するなどです。
ソフトウェアの mutex_lock の実装は、これらの状況が心配するほど重要であると考えられる場合、指数バックオフを実装しようとすると非常に複雑になる可能性があります。私が取り組んだ 128 コアのシステムでは、そうでした。
コンペア アンド スワップは、1973 年に IBM メインフレームに追加されました。これ (およびコンペア ダブル アンド スワップ) は、IBM メインフレームにまだあります (PLO などの最近のマルチプロセッサ機能 (ロックされた操作を実行する) とともに)。
x86 と Itanium には CMPXCHG (比較と交換) があります。
Sparc v9 には cas 命令があります。SPARC v9アーキテクチャ マニュアルでは、Annex J の CAS 命令の使用について説明しています。具体的には、例 J.11 と J.12 を参照してください。
現在のアドレス空間または代替アドレス空間にアクセスできるため、命令の名前は実際には「casa」であると思います。「cas」は、現在の ASI にアクセスするアセンブラ マクロです。
また、developers.sun.comの記事では、cas を含め、Sparc プロセッサが長年にわたって実装してきたさまざまなアトミック命令について説明しています。