メモリー・マッピングについて

システム上でアプリケーション命令が処理される速度は、 プログラム・アドレス可能メモリーの外のデータを 取得するのに必要なアクセス操作の回数に比例します。

システムには、これらの外部の読み書き操作に関連するトランザクションのオーバーヘッドを 減らすための方法が、2 つあります。 ファイル・データをプロセス・アドレス・スペースにマップすることができます。 また、プロセスを、相互に協力するプロセス間で共有することができる 無名メモリー領域にマップすることもできます。

メモリーにマップされたファイルには、プロセスが、ファイル・データを直接 プロセス・アドレス・スペースに組み入れることによって、 ファイルにアクセスするメカニズムがあります。 マップされたファイルを使用 すると、read および write サブルーチン が行うように、ファイル・データをプロセス・データ・バッファーにコピーする 必要がないため、入出力データの移動は大幅に削減されます。 複数のプロセスが同じファイルをマップすると、 その内容がそれらのプロセスによって共有されるので、 プロセスが同期化したり通信するためのオーバーヘッドが少ないメカニズムが得られます。

マップされたメモリー領域は、共有メモリー域とも呼ばれ、 プロセス間でデータを交換するための大型のプールとして使用することができます。 使用可能なサブルーチンは、 プロセス間のロックまたはアクセス制御を行いません。 したがって、共有メモリー域を使用するプロセスは、シグナルまたは セマフォーの制御方法をセットアップして、アクセスが競合しないようにし、 さらに、あるプロセスが別のプロセスで使用されているデータを変更 できないようにしなければなりません。 共有メモリー域が最も役立つのは、 プロセス間で交換するデータ量が多過ぎてメッセージとともに転送できないときや、 あるいは多数のプロセスが大きな共通のデータベースを維持するときです。

システムには、ファイルおよび無名メモリー領域 をマップするための方法が 2 つあります。 以下のサブルーチンは、まとめて shmat サービスとして知られ、一般に、 プログラムから共有メモリー・セグメントを作成し、使用するときに使用されます。

サブルーチン 定義
shmctl 共有メモリー操作を制御します。
shmget 共有メモリー・セグメントを入手もしくは作成します。
shmat プロセスから共有メモリー・セグメントを接続します。 ブロック・デバイスのマップは許されません。
shmdt プロセスから共有メモリー・セグメントを切り離します。
mprotect 共有メモリー・セグメント内の指定されたアドレス範囲のアクセス保護を変更します。
disclaim 共有メモリー・セグメント内の 指定されたアドレス範囲から、マッピングを除去します。

ftok サブルーチンは、shmget サブルーチンが共有セグメントを作成するために使用するキーを提供します。

2 番目のセットのサービスは、まとめて mmap サービス として知られ、通常ファイルのマッピングに使用されますが、 共有メモリー・セグメントの作成にも使用されることがあります。

ファイルの mmap() の結果のメモリーに対する有効な操作は、すべて、 ブロック・デバイスの mmap() の結果のメモリーに対しても有効です。 ブロック・デバイスは、ブロック・インターフェースを提示する デバイス・ドライバーへのアクセスを提供する特殊ファイルです。 デバイス・ドライバーへのブロック・インターフェースには、固定サイズ・ブロックの データ・アクセスが必要です。 このインターフェースは、通常、データ・ストレージ・デバイスに使用されます。

mmap サービスには、以下のサブルーチンが組み込まれています。

サブルーチン 定義
madvise システムに、プロセスの予期されるページングの振る舞いを知らせます。
mincore メモリー・ページの常駐状況を判別します。
mmap オブジェクト・ファイルを仮想メモリーにマップします。 ブロック・デバイスを一時には 1 プロセスずつマップできます。
mprotect メモリー・マッピングのアクセス保護を変更します。
msync マップされたファイルとその基本的なストレージ・デバイスを同期化します。
munmap マップされたメモリー領域をマップ解除します。

msem_initmsem_lockmsem_unlockmsem_removemsleep、および mwakeup サブルーチンは、mmap サービスを用いてマップされたプロセスのアクセス制御を行います。

メモリー・マッピングの詳細については、以下の節を参照してください。

mmap と shmat の比較

shmat サービスの場合と同様に、mmap サービスによるファイルのマッピング に使用できるプロセス・アドレス・スペースの部分は、プロセス が 32 ビット・プロセスか 64 ビット・プロセスかによって決まります。 32 ビット・プロセスの場合は、マッピングに使用できるアドレス・スペースの 部分は、0x30000000 から 0xCFFFFFFF の範囲のアドレスの、合計 2.5G バイトのアドレス・スペースとして構成されます。 以降では、ファイルのマッピングに使用できるアドレス・スペースの 部分は、0x30000000 から 0xCFFFFFFF および 0xE0000000 から 0xEFFFFFFF の範囲のアドレスの、合計 2.75G バイトのアドレス・スペースとして構成されます。 AIX® 5.2 および以降では、ベリー・ラージ・アドレス・スペース・モデルを持つ 32 ビット・プロセ スは、マッピングに使用できるアドレス・スペースの部分は、0x30000000 から 0xFFFFFFFF の範囲のアドレス の、合計 3.25G バイトです。

32 ビット・プロセス・アドレス・スペース内のすべての使用可能範囲は、 固定位置マッピングと可変位置マッピングの両方に使用することができます。 固定位置マッピングは、アプリケーションがマッピングをアドレス・スペース内の固定位置 で行うように指定したときに発生します。 可変位置マッピングは、マッピングを行うべき位置をシステム が決めるようにアプリケーションが指定したときに発生します。

64 ビット・プロセスの場合は、プロセス・アドレス・スペースで 2 セットのアドレス範囲 が、mmap または shmat マッピングに使用することができます。 最初のアドレス範囲 は、0x07000000_00000000 から 0x07FFFFFF_FFFFFFFF の 単一の範囲から構成され、固定位置マッピングと可変位置マッピング の両方に使用することができます。 2 番目のセットのアドレス範囲は、使用できるのは固定位置マッピングに対してのみ で、0x30000000 から 0xCFFFFFFF0xE0000000 から 0xEFFFFFFF、 および 0x10_00000000 から 0x06FFFFFF_ FFFFFFFF の 範囲から構成されます。 このセットの最後の範囲は、0x10_00000000 から 0x06FFFFFF_FFFFFFFF から構成されます。 この範囲もまた、プログラム・テキスト、データ、およびヒープを保持するために、システム・ローダーが使用することができます。 したがって、この範囲のなかの未使用部分のみが、固定位置マッピングに使用可能となります。

mmap および shmat サービスは、 ともにオブジェクトの同じ領域をマップする複数プロセスの機能を 備えているため、そのオブジェクトに対するアドレス能力を共有します。 しかし、mmap サブルーチンは、そのようなマッピングの数を相対的に無限 に設定できるようにして、その機能を shmat サブルーチンの機能を超 えて拡張します。 この機能で、ファイル・オブジェクトまたはメモリー・セグメントあたりの サポートされるマッピング数は増えますが、多くのプロセスがそのアドレス・スペースに 同じファイル・データをマップするアプリケーションには非効率的になります。

mmap サブルーチンには、 オブジェクトにマップするプロセスごとに固有のオブジェクト・アドレスがあります。 このソフトウェアは、別名として知られる固有の仮想アドレスを プロセスごとに指定することによってこれを行います。 shmat サブルーチンによって、 プロセスは、マップされたオブジェクトのアドレスを共有することができます。

オブジェクト内の所定のページの既存の別名で、任意の一定時点に 実アドレス変換を持つのは 1 つに限られるので、 ページ・フォールトを起こさずにそのページを参照できるのは、 mmap マッピングのうち 1 つだけです。 このページに異なるマッピング (したがって、異なる別名) が参照を行うと、ページ・フォールト が生じ、それが原因で、そのページの既存の実アドレス変換は無効になります。 その結果、異なる別名で新しい変換を設定する必要が生じます。 プロセスは、ページを、これらのさまざまな変換の間で移動することによって共有します。

多くのプロセスがそれぞれのアドレス・スペースに、同じファイル・データをマップするというアプリケーション の場合は、このプロセスの切り替えが、パフォーマンスに不利な効果を与えることがあります。 このような場合は、shmat サブルーチンが より効率的なファイル・マッピング機能を提供することがあります。

注: PowerPC® プロセッサーのシステムでは、 同じ実アドレスに複数の仮想アドレスが存在することが可能です。 実アドレスの別名を、 切り替えなしに異なるプロセスのさまざまな実効アドレスに付けることがで きます。 切り替えがないため、パフォーマンスの低下はありません。

以下の状況のもとでは、 shmat サービスを使用してください。

  • 32 ビット・アプリケーションの場合は、それぞれ 256 MB 未満の、11 以下のファイルが同時 にマップされる。
  • 256 MB より大きいファイルをマップする場合。
  • 互いに関係のない (親子関係のない) プロセス間で共有する必要がある、共有メモリー領域をマップ する場合。
  • ファイル全体をマップする場合。

以下の状況のもとでは、mmap サービスを使用してください。

  • アプリケーションの移植性が問題である。
  • 多くのファイルが同時にマップされる。
  • マップの必要があるのはファイルの一部のみである。
  • マッピングで、ページ・レベルの保護を設定する必要がある。
  • 私用マッピングが必要である。

「拡張 shmat」機能を、32 ビット・アプリケーションと そのアドレス・スペースの制約に対して使用することができます。 環境変数 EXTSHM=ON を定義すると、その環境で実行するプロセスは、11 を上回る共有メモリー・セグメントを作成し、 接続することができます。 プロセスは、これらのセグメントを、 セグメントのサイズに合わせてアドレス・スペース内に接続することができます。 同じ 256 M バイト領域の最初のセグメントの終わりに、 別のセグメントを接続することができます。 プロセスを接続できるアドレスは、SHMLBA_EXTSHM バイトの倍数である、 ページ境界にあります。

拡張 shmat 機能を使用する場合は、いくつかの制約事項があります。 これらの共有メモリー領域は、割り込みハンドラーでバッファーの 固定解除が発生する、入出力バッファーとしては使用できません。 拡張 shmat 入出力バッファーの使用上の 制約事項は、mmap バッファーの場合と同じです。

環境変数には、EXTSHM=ON のときは 11 を超えるセグメントを 接続する追加機能、あるいは環境変数が設定されないときは 11 以下のセグメントへの 高パフォーマンスのアクセスによって、アプリケーションを実行するオプションがあります。 また、「拡張 shmat」機能が適用されるのは 32 ビット・プロセスの みです。

mmap の互換性に関する考慮事項

mmap サービスは、さまざまな標準によって指定され、 一般に他のオペレーティング・システムで使用される場合、 優れたファイル・マッピング・インターフェースとして使用されます。 しかし、このシステムの mmap サブルーチンがこのシステムで 使用される場合、ほかのシステムで使用される場合とは異なる点があります。 mmap サブルーチンは、以下の変更を取り入れています。

  • プロセス専用域へのマッピングはサポートされない。
  • マッピングは暗黙的にマップ解除されない。 指定の範囲内に 既にマッピングが存在する場合は、MAP_FIXED を指定する mmap 操作は失敗します。
  • 私用マッピングの場合、コピー・オン・ライト・セマンティックは 最初の書き込み参照でページのコピーをとる。
  • 入出力またはデバイス・メモリーのマッピングは、サポートされない。
  • キャラクター型デバイスのマッピング、あるいは、 キャラクター型デバイスへの読み取り/書き込み操作のバッファーとしての mmap 領域の使用は、サポートされない。
  • madvise サブルーチンは互換性のためにだけ提供されている。 システムは、指定された助言に対してはアクションをとりません。
  • mprotect サブルーチンを用いると、 指定された領域はマップ解除されたページを入れることができる。 操作中は、マップ解除されたページはスキップされるだけです。
  • デフォルトの絶対マッピング用、および MAP_INHERITMAP_HASSEMAPHORE、および MAP_UNALIGNED フラグ用の OSF/AES 固有のオプションはサポートされない。

セマフォー・サブルーチンの使用

msem_initmsem_lockmsem_unlockmsem_removemsleep および mwakeup サブルーチンは、OSF アプリケーション環境の仕様に準拠しています。 これらは、semget および semop サブルーチンのような IPC インターフェースの代わりになります。 セマフォーを使用する利点には、効果的なシリアル化メソッドや、 セマフォーにコンテンションがない場合には システム呼び出しの必要がないなどの、オーバーヘッドの削減があります。

セマフォーは、共有メモリー領域内になければなりません。 セマフォーは、msemaphore 構造体によって指定されます。 msemaphore 構造体の値は、 すべて msem_init サブルーチン呼び出しの 結果として生じたものでなければなりません。 この呼び出しに続けて、一連の msem_lock サブルーチン または msem_unlock サブルーチンの呼び出しを行っても、 行わなくても構いません。 msemaphore 構造体値が別の方法で生じた場合、 セマフォー・サブルーチンの結果は不定です。

msemaphore 構造体のアドレスは重要です。 構造体のアドレスを変更しないように注意してください。 構造体に、別のアドレスの msemaphore 構造体からコピーされた 値が入っている場合、セマフォー・サブルーチンの結果は不定です。

セマフォー構造体が mmap サブルーチンによって作成された無名メモリー領域 に存在するときは、特に同じセマフォーを多数のプロセスが参照する場合、 セマフォー・サブルーチンが効率的でなくなる場合もあります。 このような場合、 セマフォー構造体は、shmget および shmat サブルーチン によって作成された共有メモリー領域から割り当てる必要があります。

shmat サブルーチンによるファイルのマップ

マッピングを使用すると、 ファイルの内容の書き込みや読み取りに関係するオーバーヘッドを削減することができます。 ファイルの内容が一たびユーザー・メモリーの領域にマップされると、 入出力呼び出しではなく、そのデータを指すポインターを用いて、 ファイルをメモリー内のデータであるかのように操作することができます。 ディスク上のファイルのコピーも、そのファイルのページング域として使用され、 ページング・スペースの節約になります。

プログラムは、任意の通常のファイルをマップされたデータ・ファイル として使用することができます。 マップされたデータ・ファイルの機能を、 コンパイル済みの実行可能オブジェクト・コードの入ったファイルに拡張することもできます。 マップされたファイルには通常のファイルより速くアクセスすることができるため、その実行可能オブジェクト・ファイルがファイルにマップされていれば、システムはプログラムをより迅速にロードすることができます。

プログラムを、マップされた実行可能ファイルとして作成する場合は、-K フラグ を cc または ld コマンド に使用して、プログラムをコンパイルし、リンクします。 -K フラグは、リンカーに、オブジェクト・ファイルを ページ位置合わせフォーマットで作成するように指示します。 すなわち、オブジェクト・ファイルの各部分は、ページ境界 (2 K バイトで割り切れる アドレス) から始まります。 このオプションを用いると、オブジェクト・ファイル内に若干の空スペースが生じますが、 実行可能ファイルをメモリーにマップすることができます。 システムがオブジェクト・ファイルをメモリーにマップする場合、 テキスト部分とデータ部分の処理は異なります。

コピー・オン・ライト・マップ・ファイル

マップされたファイルに加えた変更が、ディスク上のファイルにただちに 出現するのを防ぐため、ファイルをコピー・オン・ライト・ファイルとしてマップします。 このオプションを使用すると、マップされたファイルは、 ディスク上のファイルのコピーに対してではなく、 システムのページング・スペースに保管された変更とともに作成されます。 変更を保管するには、その変更をディスク上のコピーに書き込む必要があります。 そうしない場合、ファイルをクローズしたとき、その変更は失われます。

変更は、ほかのユーザーがアクセスする可能性があるファイルのコピーではただちに反映されない ため、コピー・オン・ライトのマップされたファイルを使用するのは、相互に協力するプロセス間 に限ります。

システムは、shmat サブルーチンで マップされたファイルの終わりを検出しません。 したがって、対応するメモリー・セグメント (ファイルがマップ されたところ) に保管することによって、コピー・オン・ライトの マップされたファイルの現行のファイルの終わりを超えて書き込む場合は 、ディスク上の実際のファイルはゼロのブロックで拡張され、新しいデータに備えます。 プログラムが、ファイルをクローズする前に fsync サブルーチンを使用しない場合は、以前のファイルの終わりを超えて書き込まれたデータはディスクに書き出されません。 ファイルは大きくなっているように見えますが、 入っているのは追加されたゼロだけです。 したがって、常に fsync サブルーチンを使用してから、コピー・オン・ライトの マップされたファイルをクローズし、追加もしくは変更されたデータがあればそれを保存するようにします。

shmat サブルーチンによる共有メモリー・セグメントのマップ

システムは、ファイルを作成し使用するのと同じ方法で、 共有メモリー・セグメントを使用します。 通常使用されるファイルシステムの用語に関連して、 共有メモリーに使用する用語を定義することは、 共有メモリーを理解する上で重要です。 共有メモリー用語の定義リストを以下に示します。

用語 定義
キー 特定の共有セグメントの固有の ID。 共有セグメントが存在する場合は、共有セグメントに関連します。 この点では、ファイルのファイル名 に似ています。
shmid 特定のプロセス内で使用するために、共有セグメントに割り当てられた ID。 使用においては、ファイルのファイル・ディスクリプター に似ています。
attach プロセスは、共有セグメントを使用するためには接続する必要があることを指定します。 共有セグメントの接続は、ファイルのオープンに似ています。
detach プロセスは、共有セグメントを使用し終えた後は、 それを切り離す必要があることを指定します。 共有セグメントの切り離しは、ファイルのクローズに似ています。