
コンピュータ サイエンスでは、共有メモリとは、複数のプログラムが同時にアクセスして、プログラム間の通信を可能にしたり、重複コピーを回避したりできるメモリです。共有メモリは、プログラム間でデータを渡す効率的な手段です。状況に応じて、プログラムは単一のプロセッサで実行される場合もあれば、複数の個別のプロセッサで実行される場合もあります。
単一プログラム内、たとえば複数のスレッド間の通信にメモリを使用することは、共有メモリとも呼ばれます。
ハードウェア

コンピュータ ハードウェアにおいて、共有メモリとは、マルチプロセッサ コンピュータ システム内の複数の異なる中央処理装置(CPU)からアクセスできるランダム アクセス メモリ(RAM)の (通常は大きな) ブロックを指します。
共有メモリシステムでは以下が使用される: [1]
- ユニフォーム メモリ アクセス(UMA): すべてのプロセッサが物理メモリを均一に共有します。
- 非均一メモリアクセス(NUMA): メモリアクセス時間はプロセッサに対するメモリの位置によって異なります。
- キャッシュ専用メモリ アーキテクチャ(COMA): 各ノードのプロセッサのローカル メモリは、実際のメイン メモリではなく、キャッシュとして使用されます。
共有メモリ システムは、すべてのプロセッサが単一のデータ ビューを共有し、プロセッサ間の通信が同じ場所へのメモリ アクセスと同じくらい高速になるため、比較的簡単にプログラムできます。共有メモリ システムの問題は、多くの CPU がメモリへの高速アクセスを必要とし、メモリをキャッシュする可能性が高いことです。これには 2 つの複雑な問題があります。
- アクセス時間の低下: 複数のプロセッサが同じメモリ位置にアクセスしようとすると、競合が発生します。近くのメモリ位置にアクセスしようとすると、偽共有が発生する可能性があります。共有メモリ コンピュータは、あまり拡張できません。ほとんどのコンピュータには 10 個以下のプロセッサがあります。
- データの一貫性の欠如: 1 つのキャッシュが他のプロセッサで使用される可能性のある情報で更新されるたびに、その変更を他のプロセッサに反映する必要があります。そうしないと、異なるプロセッサが一貫性のないデータで作業することになります。このようなキャッシュ一貫性プロトコルは、正常に動作する場合、複数のプロセッサ間で共有される情報への非常に高性能なアクセスを提供できます。一方、過負荷になり、パフォーマンスのボトルネックになることもあります。
クロスバー スイッチ、オメガ ネットワーク、HyperTransport、フロントサイド バスなどのテクノロジを使用して、ボトルネックの影響を緩和できます。
異種システム アーキテクチャ( CPUやGPUなどの異なるタイプのプロセッサを共有メモリと統合するプロセッサ アーキテクチャ)の場合、 CPU のメモリ管理ユニット(MMU) と GPU の入出力メモリ管理ユニット(IOMMU) は、共通アドレス空間などの特定の特性を共有する必要があります。
共有メモリの代替手段は分散メモリと分散共有メモリですが、それぞれ同様の問題を抱えています。
ソフトウェアでは
コンピュータソフトウェアでは、共有メモリは
- プロセス間通信(IPC)の方法。つまり、同時に実行されているプログラム間でデータを交換する方法です。1 つのプロセスがRAM内に他のプロセスがアクセスできる領域を作成します。
- 仮想メモリマッピングを使用するか、または問題のプログラムの明示的なサポートによって、通常はデータのコピーであるものへのアクセスを単一のインスタンスに誘導することでメモリ領域を節約する方法。これは、共有ライブラリやExecute in place (XIP)で最もよく使用されます。
両方のプロセスが通常の作業メモリのように共有メモリ領域にアクセスできるため、これは非常に高速な通信方法です(名前付きパイプ、Unixドメインソケット、CORBAなどの他のIPCメカニズムとは対照的です)。その一方で、たとえば通信プロセスは同じマシン上で実行されている必要があるため(他のIPC方法のうち、コンピュータネットワークを使用できるのはインターネットドメインソケットのみであり、Unixドメインソケットは使用できない)、メモリを共有するプロセスが別のCPU上で実行されており、基礎となるアーキテクチャがキャッシュコヒーレントでない場合は、問題を回避するために注意が必要です。
共有メモリによる IPC は、たとえば、 Unix システム上のアプリケーションとX サーバー間で画像を転送する場合や、 Windowsの COM ライブラリの CoMarshalInterThreadInterfaceInStream によって返される IStream オブジェクト内で使用されます。
動的ライブラリは通常、メモリに一度保持され、複数のプロセスにマップされます。個々のプロセス用にカスタマイズする必要があったページ (そこではシンボルが異なって解決されるため) のみが複製されます。これは通常、書き込みが試行されたときにページを透過的にコピーし、その後、プライベート コピーで書き込みを成功させる、 コピー オン ライトと呼ばれるメカニズムによって行われます。
複数アドレス空間オペレーティングシステムと比較すると、単一アドレス空間オペレーティングシステムでは、メモリ共有(特に共有プロシージャやポインタベースの構造)はより簡単です。[2]
Unix系システムのサポート
POSIX は、共有メモリを使用するための標準化された API、POSIX 共有メモリを提供しています。これは、sys/mman.h の関数を使用しますshm_open。[3] POSIX プロセス間通信 (POSIX:XSI 拡張の一部) には、共有メモリ関数、、およびが含まれています。shmat[ 4 ] [ 5] Unix System V も共有メモリ用の API を提供しています。これは、sys/shm.h の shmget を使用します。BSD システムは、複数のプロセスで使用できる「匿名マップ メモリ」を提供します。
shmctlshmdtshmget
によって作成された共有メモリはshm_open永続的です。プロセスによって明示的に削除されるまでシステム内に残ります。これには、プロセスがクラッシュして共有メモリをクリーンアップできない場合、システムがシャットダウンするまで残り続けるという欠点があります。この制限は、と呼ばれるAndroid固有の実装には存在しませんashmem。[6]
POSIX は、ファイルをメモリにマッピングするための API も提供しますmmap。マッピングは共有可能であり、ファイルの内容を共有メモリとして使用できるようになります。
2.6カーネル以降をベースにしたLinuxディストリビューションは、/dev/shmをRAMディスクの形で共有メモリとして提供しており、より具体的にはメモリに保存されるワールド書き込み可能ディレクトリ(システムのすべてのユーザーがファイルを作成できるディレクトリ)として提供されています。RedHatとDebianベースのディストリビューションはどちらもデフォルトでこれを含んでいます。このタイプのRAMディスクのサポートは、カーネル構成ファイル内で完全にオプションです。[7]
Windows でのサポート
Windowsでは、関数CreateFileMappingとMapViewOfFile関数を使用して、ファイルの領域を複数のプロセスのメモリにマップすることができます。[8]
クロスプラットフォームサポート
いくつかのC++ライブラリは、共有メモリ機能への移植可能でオブジェクト指向のアクセスを提供します。たとえば、BoostにはBoost.Interprocess C++ライブラリ[9]が含まれており、QtはQSharedMemoryクラスを提供します。[10]
プログラミング言語のサポート
POSIXバインディングを持つプログラミング言語(C/C++など)では、オペレーティングシステムが提供する関数を呼び出すことで共有メモリ領域を作成し、アクセスできます。他のプログラミング言語では、同様の効果を得るためにこれらのオペレーティングシステムを独自の方法で使用している場合があります。たとえば、PHPはPOSIX関数に似た共有メモリを作成するためのAPIを提供しています。[11]
参照
- 分散メモリ
- 分散共有メモリ
- 共有グラフィックメモリ
- 異機種混在システムアーキテクチャ
- グローバル変数
- ナノスレッド
- 現地で実行
- 共有レジスタ
- 共有スナップショットオブジェクト
- フォン・ノイマン・アーキテクチャのボトルネック
参考文献
- ^ El-Rewini, Hesham; Abd-El-Barr, Mostafa (2005).高度なコンピュータアーキテクチャと並列処理. Wiley-Interscience. pp. 77–80. ISBN 978-0-471-46740-3。
- ^ Jeffrey S. Chase、Henry M. Levy、Michael J. Feeley、Edward D. Lazowska。「単一アドレス空間オペレーティング システムにおける共有と保護」 doi :10.1145/195792.195795 1993. p. 3
- ^ Single Unix 仕様の shm_open のドキュメント
- ^ Robbins, Kay A.; Robbins, Steven (2003). Unix システムプログラミング: 通信、並行性、スレッド(第 2 版). Prentice Hall PTR. p. 512. ISBN 978-0-13-042411-2. 2011-05-13取得。POSIX
プロセス間通信 (IPC) は、POSIX:XSI 拡張の一部であり、Unix System V プロセス間通信に由来しています。
- ^ Single Unix 仕様の共有メモリ機能。
- ^ 「Android カーネルの機能」. elinux.org . 2022 年12 月 12 日閲覧。
- ^ Christoph Rohland、Hugh Dickins、KOSAKI Motohiro. 「tmpfs.txt」. kernel.org . 2010-03-16閲覧。
- ^ MSDN からの名前付き共有メモリの作成。
- ^ Boost.Interprocess C++ ライブラリ
- ^ 「QSharedMemory クラス リファレンス」。
- ^ PHP-API の共有メモリ関数
外部リンク
- IPC:共有メモリ (Dave Marshall 著)
- 共有メモリの概要、Richard Stevens 著「UNIX ネットワーク プログラミング、第 2 巻、第 2 版: プロセス間通信」の第 12 章。
- SharedHashFile、オープンソースの共有メモリハッシュテーブル。
