(Translated by https://www.hiragana.jp/)
共有メモリ - Wikipedia コンテンツにスキップ

共有きょうゆうメモリ

出典しゅってん: フリー百科ひゃっか事典じてん『ウィキペディア(Wikipedia)』

情報処理じょうほうしょりにおいて共有きょうゆうメモリ(きょうゆうメモリ)とは、複数ふくすうのプログラムが同時どうじ並行へいこうてきにアクセスするメモリである。

概要がいよう

[編集へんしゅう]
3つのプロセッサによる共有きょうゆうメモリシステムの

複数ふくすうのプログラムあいだ通信つうしん手段しゅだんとして使つか場合ばあいと、たん複製ふくせい用意よういする冗長じょうちょうさをふせ目的もくてき場合ばあいなどがある。共有きょうゆうメモリはプログラムあいだでデータをやりとりする効率こうりつてき手段しゅだんである。文脈ぶんみゃくによって、それらプログラムが単一たんいつのプロセッサじょう動作どうさする場合ばあい複数ふくすうことなるプロセッサぐんじょう動作どうさする場合ばあいがある。単一たんいつのプログラムの内部ないぶでメモリを使つかって通信つうしんする場合ばあいもあり、たとえばマルチスレッド典型てんけいてきだが、仮想かそう空間くうかんをもともと共有きょうゆうしている場合ばあいは「共有きょうゆうメモリ」とはばない。

ハードウェアによる共有きょうゆうメモリ

[編集へんしゅう]

コンピュータのハードウェアによる共有きょうゆうメモリは、マルチプロセッサシステムにおける複数ふくすうCPUがアクセスできるRAMの(通常つうじょうおおきなブロックを意味いみする。

共有きょうゆうメモリシステムでは、ぜんプロセッサがデータを共有きょうゆうしているためプログラミングが比較的ひかくてき容易よういで、おなじメモリ位置いちへのアクセスによって高速こうそくなプロセッサあいだ通信つうしん可能かのうである。問題もんだいは、CPUはなるべく高速こうそくなメモリアクセスを必要ひつようとするため、それぞれにキャッシュメモリっていることがおおてんである。そのため、以下いかの2つの問題もんだいしょうじる。

  • CPU-メモリあいだボトルネックになりやすい。共有きょうゆうメモリがたコンピュータはあまりプロセッサすうやせない(CPUをやしてもCPUすう比例ひれいして性能せいのう強化きょうかされなくなる)。おおくの場合ばあい、10かそれ以下いかのプロセッサすうである。
  • キャッシュコヒーレンシ問題もんだい。あるキャッシュじょうであるメモリ位置いち情報じょうほう更新こうしんされ、それをのプロセッサが必要ひつようとする場合ばあい、その更新こうしんのプロセッサにも反映はんえいさせなければならない。さもないとそれぞれのプロセッサが一貫いっかんしていないデータを使つかって動作どうさすることになる。そのためのプロトコルをコヒーレンシプロトコルとび、それがうまく機能きのうすれば複数ふくすうのプロセッサが高速こうそく共有きょうゆうメモリ(うえ情報じょうほう)にアクセスできるようになる。しかし一方いっぽうで、コヒーレンシプロトコルがオーバーヘッドとなり、性能せいのうのボトルネックになることもある。

ボトルネック問題もんだいやわらげる技術ぎじゅつとして、クロスバースイッチオメガネットワーク英語えいごばんHyperTransportCPUバス分離ぶんりフロントサイドバスとバックサイドバス、ひとし)などがある。

共有きょうゆうメモリ以外いがい方式ほうしきとして分散ぶんさんメモリ英語えいごばん分散ぶんさん共有きょうゆうメモリがあるが、どちらにもたような問題もんだいがある。また、NUMA参照さんしょう

GPUない共有きょうゆうメモリ

[編集へんしゅう]

GPGPU対応たいおうしたモダンなGPUは、GPUのスレッドブロック(ワークグループ、スレッドグループ)ないでのみアクセス可能かのう共有きょうゆうメモリ(ローカルメモリ、グループ共有きょうゆうメモリ)をゆうしている。この共有きょうゆうメモリは、VRAMうえ確保かくほされるグローバルメモリとくらべるとしょう容量ようりょうだが高速こうそくであり、アプリケーションコードから操作そうさ可能かのうなキャッシュメモリの役割やくわりたす[1]CUDAOpenCLDirectComputeのようなAPIは、それぞれ名称めいしょうことなるものの、このGPU共有きょうゆうメモリを利用りようする機能きのうち、グローバルメモリからしたデータをGPUのスレッドブロックない共有きょうゆうしたり、計算けいさん結果けっか交換こうかんしたりする用途ようと活用かつようすることで、高速こうそくはかることができる。

ソフトウェアによる共有きょうゆうメモリ

[編集へんしゅう]

ソフトウェアにおける共有きょうゆうメモリは、以下いかのいずれかを意味いみする。

  • プロセスあいだ通信つうしん (IPC) の技法ぎほうひとつ。同時どうじ動作どうさしているプログラムあいだでデータを交換こうかんする方法ほうほうである。1つのプロセスがメモリじょうのプロセスからもアクセスできる領域りょういき作成さくせいする。
  • 通常つうじょう、アクセスする主体しゅたいごとにコピーを用意よういするようなデータがあるとき、仮想かそう記憶きおく機構きこうなんらかの明示めいじてきプログラム機構きこう使つかってそれらがおな実体じったい物理ぶつりメモリ)をアクセスするようマッピングすること。共有きょうゆうライブラリXIP (Execute in Place) でよく使つかわれる。
  • スレッド実装じっそう一方いっぽうしき

プロセスぐん共有きょうゆうメモリ領域りょういき通常つうじょうのメモリ領域りょういきおなじようにアクセスできるので、のプロセスあいだ通信つうしん名前なまえきパイプソケットCORBAなど)と比較ひかくして通信つうしん手段しゅだんとしては非常ひじょう高速こうそくである。しかし、プロセスぐんおなじマシンじょう動作どうさしなければならないという制約せいやくがあり(のIPC手段しゅだんはネットワークじょうでも機能きのうする)、プロセスが別々べつべつのCPUじょう動作どうさする場合ばあいはハードウェアによる共有きょうゆうメモリを使つかっていることになり、キャッシュコヒーレンシなどに注意ちゅうい必要ひつようとなる。プロセスあいだ通信つうしんFIFOストリームかた場合ばあいは、名前なまえパイプ通信つうしん手段しゅだんとして検討けんとうすべきである。一般いっぱん共有きょうゆうメモリ自体じたい保護ほご機能きのうをもたないので動作どうさ高速こうそくである。しかし共有きょうゆうされるメモリは不定ふていのタイミングで複数ふくすうのプロセスからアクセスされる可能かのうせいがある。競合きょうごうけるためにはセマフォやロックなどで競合きょうごう回避かいひしなければならない。

共有きょうゆうメモリによるIPCは、たとえばUNIXうえXサーバとアプリケーションのあいだ画像がぞう転送てんそうする場合ばあいや、WindowsCOMライブラリで CoMarshalInterThreadInterfaceInStream() 関数かんすうかえIStream オブジェクトの内部ないぶ使つかわれている。一般いっぱんてき共有きょうゆうメモリが使つかわれるアプリケーションとしてOracleなどのデータベースがある。UnixばんOracleではSGAとばれる共有きょうゆうメモリ空間くうかんにデータベースバッファキャッシュがおかれて複数ふくすうのプロセスからアクセスさせて性能せいのう向上こうじょうはかっている。

動的どうてきライブラリ一度いちどメモリじょうかれると、それが複数ふくすうのプロセスにマッピングされ、プロセスごとにカスタマイズされるページぐん(シンボル解決かいけつちがいがしょうじる部分ぶぶん)だけが複製ふくせいされ、通常つうじょうコピーオンライトという機構きこうで、そのページにもうとしたときにコピーがおこなわれる。

UNIXでのサポート

[編集へんしゅう]

POSIX には共有きょうゆうメモリの標準ひょうじゅんAPIとして POSIX Shared Memory がある。これは、sys/mman.h にある shm_open という関数かんすう使つか[2]。POSIXのプロセスあいだ通信つうしん(POSIX:XSI拡張かくちょう一部いちぶ)には共有きょうゆうメモリ関数かんすうとして shmatshmctlshmdtふくまれている[3][4]

shm_open生成せいせいされた共有きょうゆうメモリは永続えいぞくてきであり、プロセスが明示めいじてき削除さくじょしないかぎりシステムない存在そんざいつづける。ただしこれには欠点けってんもあり、共有きょうゆうメモリを削除さくじょすべきプロセスがそのまえ異常いじょう終了しゅうりょうしたとき、その共有きょうゆうメモリがシステムのシャットダウンまで残存ざんそんつづけることになる。そのような問題もんだいけるには、mmap使つかって共有きょうゆうメモリを作成さくせいすればよい[5]。2つの通信つうしんしあうプロセスがおな名前なまえ一時いちじファイルをオープンし、それにたいしてmmapすることでファイルをメモリにマッピングする。結果けっかとして、メモリマップされたファイル(メモリマップトファイル)への変更へんこうはもう一方いっぽうのプロセスからも同時どうじ観測かんそくできる。この技法ぎほう利点りてんは、両方りょうほうのプロセスが終了しゅうりょうしたとき、OSが自動的じどうてきにファイルをクローズし、共有きょうゆうメモリを削除さくじょするてんである。

Linuxカーネル 2.6 では、RAMディスク形式けいしき共有きょうゆうメモリとして /dev/shm が導入どうにゅうされた。より正確せいかくえば、だれでもめるメモリないのディレクトリであり、その容量ようりょう上限じょうげんは /etc/default/tmpfs で指定していできる。/dev/shm 機能きのうサポートはカーネルの設定せっていファイル指定していでき、デフォルトでは無効むこうとなっている。なお、RedHatDebian ベースのディストリビューションではデフォルトで有効ゆうこうになっている。

Androidでのサポート

[編集へんしゅう]

Android では Linux カーネルを使用しようしているが、IPC 関係かんけい一部いちぶ無効むこうになっており、独自どくじ開発かいはつした(現在げんざいはLinuxカーネルにはいっている)ashmem (anonymous shared memory) を使用しようしている。メモリが不足ふそくしたときにカーネルが解放かいほうする仕組しくみがあり、解放かいほうされないようにするには、ashmem_pin_region()使つか指定していする。

Windowsでのサポート

[編集へんしゅう]

Microsoft Windowsでは、Win32 APICreateFileMapping()関数かんすう使つかって共有きょうゆうメモリ(メモリマップトファイル)を作成さくせいすることができる[6]。クライアントがわプロセスはOpenFileMapping()関数かんすう使つかって、ホストがわプロセスにて作成さくせいみの共有きょうゆうメモリのハンドルを取得しゅとくすることができる。共有きょうゆうメモリをかくプロセスのアドレス空間くうかんにマッピングするにはMapViewOfFile()関数かんすう使つかう。

なおWindows APIには、CreateSharedMemory() [7][8]など “-SharedMemory” の名前なまえ関数かんすうがあるが、これはセキュリティ関連かんれんのAPIであり、メモリ共有きょうゆうのためのAPIではない。これをメモリ共有きょうゆうのために使用しようすれば、リソースを大量たいりょう消費しょうひしシステムリソースを使つかたす可能かのうせいがある。

プログラミング言語げんごごとのサポート

[編集へんしゅう]

一部いちぶC++ライブラリは、共有きょうゆうメモリ機能きのうへの移植いしょくせいたかいオブジェクト指向しこうてきなアクセスを提供ていきょうしている。たとえば、Boost C++ライブラリには Boost.Interprocess があり[9]POCO C++ Libraries には Poco::SharedMemory、Qt には QSharedMemory クラスがある[10]

PHP では POSIX で定義ていぎしている関数かんすうぐんとよく共有きょうゆうメモリようAPIが存在そんざいする[11]

.NET Frameworkはバージョン4でSystem.IO.MemoryMappedFiles.MemoryMappedFileクラス[12]標準ひょうじゅんした。.NET CoreあるいはXamarin (Mono) をつうじて、Windows以外いがいほかのプラットフォームでも利用りようできる。

脚注きゃくちゅう

[編集へんしゅう]
  1. ^ CUDAプログラミングの基本きほん / パート II - カーネル | NVIDIA
  2. ^ Documentation of shm_open from the Single UNIX Specification
  3. ^ Robbins, Kay A.; Steven Robbins (2003). UNIX systems programming: communication, concurrency, and threads (2 ed.). Prentice Hall PTR. p. 512. ISBN 978-0-13-042411-2. https://books.google.co.jp/books?id=tdsZHyH9bQEC&redir_esc=y&hl=ja 2011ねん5がつ13にち閲覧えつらん. "The POSIX interprocess communication (IPC) is part of the POSIX:XSI Extension and has its origin in UNIX System V interprocess communication." 
  4. ^ Shared memory facility from the Single UNIX Specification.
  5. ^ Stevens, Richard (1999). UNIX Network Programming, Volume 2, Second Edition: Interprocess Communications. (2 ed.). Prentice Hall PTR. p. 311. ISBN 0-13-081081-9 
  6. ^ Creating Named Shared Memory - Windows applications | Microsoft Docs
  7. ^ CreateSharedMemory function (Windows), Internet Archive
  8. ^ LSA_CREATE_SHARED_MEMORY (ntsecpkg.h) - Win32 apps | Microsoft Learn
  9. ^ Chapter 16. Boost.Interprocess - 1.80.0
  10. ^ QSharedMemory Class Reference
  11. ^ PHP 共有きょうゆうメモリ関数かんすう
  12. ^ MemoryMappedFile Class (System.IO.MemoryMappedFiles) | Microsoft Docs

関連かんれん項目こうもく

[編集へんしゅう]

学習がくしゅう参考さんこうしょ

[編集へんしゅう]

外部がいぶリンク

[編集へんしゅう]