Develop and Download Open Source Software

OpenSource Downloads

7-Zip  (4,014)  
HandBrake Japanese Language Version  (2,964)  
CrystalDiskInfo  (1,714)  
Boookends  (1,269)  
CrystalDiskMark  (874)  
Tera Term  (825)  
CotEditor  (626)  
FFFTP  (593)  
えこでこツール  (532)  
10  ffdshow  (524)  
11  SMPlayer  (503)  
12  Cabos  (492)  
13  ギコナビ  (475)  
14  Rappelz Server  (471)  
15  MergeDoc  (457)  
More >>

最近ブックマークされた記事

64GB超RAMサポート

2003年07月10日 11:53 4G/4G分割VMによる大容量RAMサポートパッチのアナウンス
Linuxカーネルのバージョン2.6では、大容量RAMサポート強化が一つの目標とされています。バージョン2.4においても、理論的には64GBまでのRAMがサポートされていましたが、現実的には16-32GB程度が限界でした。先日、Ingo Molnar氏から64GB超のRAMサポートの公開リリースがLinux Kernel MLにアナウンスされました。

Linuxカーネルバージョン2.4のRAMサポート

Linuxカーネルバージョン2.4では、カーネルコンパイル時のオプションとして、 RAM容量を選べ、1GB未満、1GB以上4GB未満、4GB以上64GB未満を選べます。 しかし、実際には16-32GB程度が限界でした。なぜそうだったのか、今後どうなるのか、Ingo Molnarは明らかにしています。

Linux 2.6での大容量RAMサポート

Linuxカーネルバージョン2.6では、64GB以上のRAMをサポートできる VMモードを選択できるようになります。これは、4G/4G split modeと よばれることになるでしょう。

以下は、Ingo Molnar氏によるLinux Kernel MLへのアナウンスの翻訳です。

メール本文

Subject: [announce, patch] 4G/4G split on x86, 64 GB RAM (and more) support
From: Ingo Molnar
Date: Wed, 9 Jul 2003 00:45:52 +0200 (CEST)

Linux カーネル 2.5.74 向けの "4GB/4GB VM分割"パッチの最初の公開リリースを アナウンスします。パッチは、 http://redhat.com/~mingo/4g-patches/4g-2.5.74-F8 になります。

4G/4G分割機能とは、主として、システムコールごとのTLBフラッシュオーバーヘッドの 費用を払っても、よりカーネルユーザVMを欲しい(または必要とする)ような、 より多くのRAMを搭載したx86システムを対象としています。

x86 では、仮想メモリの総量は、公知のとおり、4GBに制限されています。 この全4GBのVMにおいて、ユーザ空間は3GB(0x00000000-0xbfffffff)使っており、 カーネルは1GB(0xc0000000-0xffffffff)使っています。このVMの仕組みは、 3/1分割と呼ばれています。この分割方法は、RAMが1GB以下の領域では完璧に うまく稼動します。そして、'highmem' 機能によって、たくさんの大きなキャッシュ (とオブジェクト)を上位メモリエリアへ移動するものの、まあまあ 十分にうまく稼動します。

しかし搭載RAMの総量が増加してくると、3/1分割は、実際のところボトルネックに なってきます。highmemを、かなりの数の大きなサイズのキャッシュで使っているにも かかわらず、最も重要なデータ構造体の一つである mem_map[] は、カーネルVMの1GBの中から 割り当てられます。32GBのRAMを使っている場合、残る0.5GBの低位メモリ領域と いうのは大変な制限で、全てのRAMの1.5%しか表せないことになります。 様々な共通の負担が低位メモリ領域を使いはたし、人為的なボトルネックをつくり出す ことになります。64GBのRAMを使っている場合、mem_map[]だけでほとんど1GB近く使ってしまい カーネルがブートできなくなります。mem_map[]を高位メモリへ再割り当てすることは、 VM、低レベル機種依存コード、ドライバ、ファイルシステムなどの全カーネルと、 この中心的データ構造体との緊密な結合から考えて、まったくもって非現実的です。

4G/4Gパッチによって、カーネルは4G/4Gモードでコンパイルできるようになります。 このモードは、分離された全て4GBのVMをカーネルへ割り当て、それとは別の全(しかも プロセスごとに)4GBのVMをユーザ空間へ割り当てます。

4G/4Gカーネルで動作している典型的なプロセスの /proc/PID/maps ファイルは、 以下のように全4GB分のアドレス空間で動いているのが見て取れます。

 00e80000-00faf000 r-xp 00000000 03:01 175909     /lib/tls/libc-2.3.2.so
 00faf000-00fb2000 rw-p 0012f000 03:01 175909     /lib/tls/libc-2.3.2.so
 [...]
 feffe000-ff000000 rwxp fffff000 00:00 0

スタックは 0xff000000 (4GB引く16MB) までに配置されます。カーネルは4GBの低位メモリ 領域を持つため、64GBのRAMを搭載したとしても、3.1GBがまだ利用可能になっています。

 MemTotal:     66052020 kB
 MemFree:      65958260 kB
 HighTotal:    62914556 kB
 HighFree:     62853140 kB
 LowTotal:      3137464 kB
 LowFree:       3105120 kB
低位メモリ(lowmem)の総量は、それでも4GBメモリ搭載システムの3倍以上あり、 32GBのシステムでも3/1分割の場合の6倍以上あります。

4G/4G機能の性能への影響:

4G/4Gパッチを適用したときの動作時のコスト:カーネルとユーザ空間VMで 分離したアドレス空間を実装するため、entry/exit コードはカーネルページテーブルと ユーザページテーブルを切替える必要があります。これは、TLBミスでいうところの 非常にコストのかかる操作であるTLBフラッシュ(これは、キャッシュからとってこれるならば インテルCPUでは非常に高速です)ではなく、直接的なTLBフラッシュコスト(%cr3操作)が システムエントリー時に発生します。

RAMの制限:

理論的には4G/4Gパッチは、1GBの低位メモリを残しながら、x86で200GB(!)の 物理RAM分のmem_map[]を提供できます。つまり座席には足を伸ばせるだけの広さが 十分あると言うわけです。大量のRAMを搭載する正しいソリューションというのは、 正式な64-bitシステムを使うことだけれど、現状でも多くのx86ハードがあり、 今後数年に渡ってx86売られ続けるだろうことから、我々は最大限のサポートを 行うべきでしょう。

パッチは、wliのpgclパッチ(訳注:mem_map[]用の空間をNUMA-Q MPのノード0以外はbootmemから掃きだして64GB RAMをサポートする)と直交しています。両パッチは、同じことを違った 方法でやろうとしています。私は、いずれ二つのパッチを結合したいと思っており、作業量の見積もりもできています。

実装の詳細:

パッチは、たくさんの低レベル x86 コードインフラを実装/変更します。

  • GDT, IDT, TSS, LDT, vsyscallページとカーネルスタックを高位仮想メモリウインドウ 4GBアドレス空間のトップ16MBの(トランポリン)へ移動します。
  • atomic kmaps の高位メモリ依存性を解除します。
  • LDTを atomic kmap化します。
  • (そして、初期マップサイズの増加やカーネルVMの全4GBをマップするPAEコードの修正 など、その他のより小さな細かい部分がたくさん)

我々が、ユーザモードからsyscall(や他の全てのトラップ)を行うときは必ず、 高位アドレス esp0 における、高位アドレスのトランポリンコードが動作を開始 します。このコードはカーネルページテーブルへと切替えて、その後「仮想カーネル スタック」から、通常の(本当の)カーネルスタックへと切替えます。システム コールexit時は、逆方向のことを行います。

いくつか一般的なカーネルの変更を同様に行います:

  • 'indirect uaccess' プリミティブを実装し、全ての get_user/put_user/copy_to_user/... などの関数が、直接のユーザ空間へのアクセスを避けて実装されます。
  • PAGE_OFFSET が PAGE_OFFSET_USER と PAGE_OFFSET (kernel)へと分割されます。
  • PAGE_OFFSET が PMD_SIZE へアライメントされると言う前提を数個修正します。
しかしパッチがカーネル全般へ及ぼす影響は極めて小さい物です。

パッチは、kernel <-> kernel コンテキストスイッチを最適化し、IRQエントリー 同様、TLBをフラッシュさせません。唯一の例外は、ユーザ空間のページテーブルを ロードした時に限られます。

よくあるx86 サーバにおける4G/4Gの典型的なコストは、システムコールの遅延で 3 マイクロ秒増える程度です(これには1マイクロ秒以下のnullシステムコールの 遅延が加算されます)。典型的なアプリケーションの負荷(DBの負荷やネット ワーキングなど)では、負荷によっては、無視できない程度の0%から30%の オーバーヘッドとなって表われます。マイクロベンチマークとは別に、同様に システムコールの遅延が増えることで、大きな速度低下が見られることがあります。

私は、4G/4G パッチは16GBのRAM容量以下では、システムのオーバーヘッドに見合うだけの 利点は無いと思います。(しかし例外はあって、特にlowmemに強烈に負荷が反応 する場合です)。32GBのRAM容量では、lowmemの制限に引っかかるため、4G/4Gパッチが とても推奨されます。そして、64GBやそれ以上のシステムでは、必須だと思います。

現状と将来計画:

パッチは作業中のスナップショットです。まだ、いくつかTODO(作業予定)とFIXME(修正項目)がありますが、 コンパイルも動作も私のところではうまくいっています。でも、 注意深く取り扱ってください。これは、かなり濃い変更が低レベルのx86コードに 加わるような、実験的なパッチです。

数個の性能向上がこのパッチの開発先端に含まれており、数日中にはこのパッチへ 統合するつもりです。しかしまずベースパッチをリリースしたいと考えました。

とにかくまあ、このパッチを試してみて。いつものように、コメントや提案は歓迎です。

	Ingo

関連トピック

最終更新:2007年07月01日 19:05