コピーオンライト

コピーオンライト (Copy-On-Write) とは



コピーオンライト(Copy-On-Write、略してCOWまたはCoW)は、コンピュータプログラミングにおける最適化手法の一つです。特に、データの複製を伴う処理において、その効率性を大幅に向上させることを目的としています。

基本的な仕組み



通常、データコピーが必要な場合、システムは新しい領域を確保し、元のデータを複製(ディープコピー)します。しかし、コピーされたデータが書き換えられない場合、このコピー処理は無駄になることがあります。そこでコピーオンライトでは、データのコピーを要求されても、実際には元のデータを参照させるだけで、コピー処理を後回しにします。この状態では、データの読み取りは問題なく行え、コピーによるコストはほぼ発生しません。しかし、元のデータやコピーされたデータを変更する際には、それぞれのデータが独立している必要があり、安易な書き換えはできません。そのため、データの書き換えが発生した時点で初めて、新しい領域を確保し、データのコピーを行います。これがコピーオンライトの基本的な流れです。

この手法の基盤となる考え方は、複数の要求者がリソースを要求した際に、当初はそれらを区別する必要がない場合に、同じリソースを共有することです。そして、要求者がリソースを「更新」しようとするまで、リソースの共有を維持します。「更新」が発生した際には、他の要求者に影響を与えないように、個別のコピーを作成します。この一連の動作は、要求者からは見えません。

コピーオンライトの最大の利点は、要求者が全く更新を行わなければ、個別のコピーを作成する必要がない点にあります。これにより、リソースの無駄な消費を抑え、処理の効率化を図ることができます。

仮想記憶への応用



コピーオンライトは、特に仮想記憶方式のオペレーティングシステム(OS)で頻繁に使用されます。例えば、プロセスのコピー(fork)を行う際、書き換えの必要がないメモリページは、元のプロセスと複製されたプロセスで共有します。一方、書き換えの可能性があるメモリページについては、新たにメモリを割り当ててコピーを作成する必要があります。この時にコピーオンライトが利用されます。

片方のプロセスがメモリを更新しようとすると、OSのカーネルがその操作を検出し、メモリのコピーを作成し、他方のプロセスから変更が見えないようにします。また、標準Cライブラリの`calloc()`関数の実装にも利用されることがあります。`calloc()`は、メモリ領域をゼロで初期化して確保する関数ですが、最適化された実装では、ゼロで初期化されたページをシステムに一つ用意しておき、`calloc()`で確保した領域にはこのページをマッピングして、コピーオンライト機能を活用します。これにより、`calloc()`呼び出し直後は、大量のメモリが必要な場合でも、物理的には1ページしか使用されず、領域を更新しようとした際に、初めて個別のコピーが作成されます。このような最適化は、通常、ページサイズ以上の大きなアロケーションに対して適用されます。

コピーオンライトは、MMU(メモリ管理ユニット)に対し、プロセスのアドレス空間の一部分が読み取り専用であると通知することで実現されます。そして、その領域への書き込みを試みると、MMUは例外を発生させ、カーネルがその例外を処理します。カーネルは、新しい物理ページを確保し、書き込みを行った領域のマッピングを変更して、新しい物理ページに対応させます。

COWの利点は、メモリを空間的にまばらに利用できる点です。データを格納した時にのみ物理メモリ使用量が増加するため、非常に効率的なハッシュテーブルを実装できます。ただし、仮想空間を使い切ってしまう危険性もあります。また、カーネルレベルでのCOWの複雑さも考慮すべき点です。カーネル自身がコピーオンライト制御されているページに書き込みを行った場合も、コピーが必要になります。

ファイルシステムへの応用



コピーオンライトは、ファイルシステムにおけるスナップショット機能を実現するアルゴリズムとしても利用されます。特定の時点のファイルシステムの状態を原本とし、ファイルやブロックの変更があった場合には、オリジナルのコピーを作成し、変更をそのコピーに反映します。これにより、論理ボリュームマネージャや多くのファイルシステムが、スナップショット機能を実装しています。

また、単純なファイルのコピーも、コピーオンライトで効率化できます。ファイルシステムがCOWをサポートし、OSがファイルコピー用のAPIを提供し、アプリケーションがそれを使用することが条件となります。Apple File System (APFS) はCOWをサポートしており、ファイルのコピーは瞬時に完了します。Microsoft WindowsのResilient File System (ReFS) もCOWをサポートしており、Windows 11のバージョン22H2以降では、開発ドライブ(Dev Drive)と対応APIによって、ファイルのCOWが利用可能になっています。さらに、プレビュー版では、従来のWindows APIである`CopyFile()`関数でも、対応環境上であればCOWを利用できるようになっています。

ファイルシステムが重複排除機構を備えている場合、コピーオンライトとの相性はさらに良くなります。COWでコピーされたファイルは、元ファイルと同一のデータブロックを参照するため、コピー終了時点で重複排除済みとみなすことができます。これにより、コピー後のファイルに対する重複排除処理が不要になります。

その他、BochsやQEMUといった仮想マシンの仮想ディスク装置でも使用されています。同じディスクイメージで複数の仮想マシンを動作させることで、必要なディスク容量を大幅に削減できます。また、ディスクからの読み込みイメージがメモリにキャッシュされ、仮想マシン間で共有されるため、性能も向上します。

制限事項



コピーオンライトには、いくつかの制限事項も存在します。例えば、ファイル上の既存のデータを更新する場合、COW処理のために一定の空き容量が必要です。これは、データ更新中に、更新前後のデータが一時的にファイルシステムに存在するためです。コピーオンライト処理に必要な空き領域が不足すると、ファイルシステムに空きがあるにも関わらず容量不足のエラーが発生することがあります。

その他の応用



コピーオンライトは、カーネル以外にも、ライブラリ、アプリケーション、システムコードなどで使用されます。C++のStandard Template Libraryが提供する`std::string`クラスも、かつてはコピーオンライト型の実装が可能でした。しかし、マルチスレッド環境では、リソースを複数のスレッドで共有するためにロックが必要となり、COWの利点以上のオーバーヘッドが発生する可能性があり、現在は推奨されていません。

まとめ



コピーオンライトは、メモリ使用量と処理時間を効率化する強力な最適化手法です。仮想記憶、ファイルシステム、仮想マシンなど、様々な分野で活用されており、現代のコンピュータシステムにおいて重要な役割を果たしています。しかし、複雑さや制限事項も存在するため、使用する際にはこれらの点を考慮する必要があります。

もう一度検索

【記事の利用について】

タイトルと記事文章は、記事のあるページにリンクを張っていただければ、無料で利用できます。
※画像は、利用できませんのでご注意ください。

【リンクついて】

リンクフリーです。