不可分操作不可分操作(ふかぶんそうさ)あるいはアトミック操作 (英: atomic operation) とは、情報工学においていくつかの操作を組み合わせたもので、システムの他の部分から見てそれらがひとつの操作に見えるものをいう。 条件不可分操作は、以下の2つの条件を満たさなければならない。
システムの他の部分から見て、操作の組合せが一度に成功したか失敗したように見える。途中の状態にアクセスすることはできない。このため不可分操作あるいはアトミック操作(= 原子操作)と呼ぶのである。 マルチプロセッサでなくとも、この実装は重要である。制御の流れが変更される可能性がある限り、不可分性がなければシステムが不正な状態になってしまう可能性がある。 単純な例例えば、プロセスがあるメモリ位置の内容をインクリメントしているとする。その処理の流れは以下のようになる:
ここで、2つのプロセスが一箇所の共有メモリ上の位置の内容をインクリメントすると仮定する:
ここで、1番目のプロセスが加算結果を書き戻す前にサスペンドされ、2番目のプロセスが走行し始めたとする:
ここで、2番目のプロセスがサスペンドされ、1番目のプロセスが再度走行する:
これは些細な例である。実際のシステムでは、操作はより複雑で、微妙なエラーとなって現われるかもしれない。例えば、64ビットの値をメモリから読む操作は32ビットのリードを2回行うことで実現されている場合がある。プロセスが最初の32ビットをリード後、次の32ビットをリードする前に値が変更されるかもしれない。結果として得られた64ビット値は変更前とも変更後とも異なる無意味な値となる。 さらに、このような結果はプロセスの動作する順番に依存しており、デバッグしようとしても検出が難しい。 CPUアーキテクチャによる違いとロックカウンタのインクリメント/デクリメントは、RISCアーキテクチャの場合、上記の例のようにリードとライトが別々の命令で行われるために、そのままでは不可分操作にできない。しかし、x86アーキテクチャのようなCISCでは、インクリメントやデクリメントを1命令で実行する命令が存在するため、それだけで不可分性が成立する。必要最小限の不可分操作は、結局テスト・アンド・セットのような指定されたメモリアドレスへのリードとライトを不可分に行う操作となる。しかし、RISCアーキテクチャは 1命令で複数回のメモリアクセスを行わないのが基本思想であるため、直接テスト・アンド・セット命令を実装することはできない(テスト・アンド・セットを命令として実装する場合、バスをロックしてリードとライトを行って他のバスマスタがメモリアクセスを途中で発行できないようにしている)。そのためにコンペア・アンド・スワップやLoad-Link/Store-Conditionalといった不可分操作が使われるようになった。 上記の例は「クリティカルセクション」のまわりでロックを獲得することで解決するように見える。しかし、ロックもハードウェアのサポート無しでは単なるメモリ上のデータでしかない。スピンロックなどのアルゴリズムをソフトウェアだけで実装することは可能だが、効率的ではない。そのために、上述のテスト・アンド・セットなどの不可分操作が最近のプロセッサで実装されており、そういった機能でロックを実装する。 関連項目 |