X86アーキテクチャ上のLinuxカーネルのデフォルトのメモリページサイズは4 KBでしたが、それはどのように計算されたのでしょうか。なぜですか。
デフォルトのページサイズは、CPUのMMU(メモリ管理ユニット)がサポートするものによって固定されます。32ビットプロテクトモードでは、x86は2種類のページをサポートします。
すべてのx86プロセッサーがラージページをサポートするわけではありません。ページサイズ拡張(PSE)機能を備えたCPUが必要です。これには、Pentium以前のプロセッサは含まれません。事実上すべての現世代のx86 CPUがそれを実装しています。
4 KiBは、他のアーキテクチャーでも広くページラーの粒度です。このサイズは、32ビットの仮想アドレスがページディレクトリ/テーブルの2つの10ビットインデックスに分割されたものであり、残りの12ビットは4 KiBのページサイズを提供すると考えられます。
32ビットアーキテクチャの4KBの通常のページサイズの設計は、実際には非常に興味深いものです。
そして、それが合理的である理由を示すために、追加の回答を追加したいと思います。
x86は「2レベルのページテーブル」を使用して、仮想メモリアドレスを物理メモリアドレスに変換します。
したがって、ページディレクトリとページテーブルの両方に エントリ、およびページサイズは バイト。をフル活用する アドレス、私たちは持っています:
ページディレクトリ/テーブルの各エントリは4バイト(32ビット)を消費するため、次のようになります。
したがって、y = 12であり、バイト単位のページサイズは = = 4KB。
そして、「1レベルのページテーブル」はどうですか?論理的にはアドレス検索に単一のページテーブルを使用できるため、これは興味深いものです。
ページディレクトリに エントリ、各アドレスを対応するページにマッピングし、ページサイズは バイト。
繰り返しになりますが、 アドレス、私たちは必要です:
そして:
Y = 17が得られ、ページサイズは = = 128KB。
また、「2レベルのページテーブル」バージョンでは、ページディレクトリとページテーブルのサイズが異なる可能性があると主張する場合もあります。ただし、これは、複数のメモリページを占有する大きなページディレクトリを使用することを意味します。悲しいことに、新しいユーザープロセスが生成されるたびに、独自のページディレクトリに対して、OSは連続したページを割り当てる必要がありますが、これは設計上エレガントではありません。
多くのアーキテクチャでは、デフォルトのページサイズは4 KBです。 巨大なページ モードに切り替えることで、一般に(AMD64の1 GBなど、多くの場合)増やすことができます。これにより、ページテーブルを小さくできるため、パフォーマンスが向上します。
ページング仮想メモリ技術をサポートした最初のIntelプロセッサは Intel 80386 でした。プロセッサは、単一のページサイズ、4 KBをサポートしていました。 1985年にリリースされて以来、Intelがその特定のページサイズを選択した理由を理解するには、その期間に戻る必要があります。
Atlas は、ページサイズが3 KBのページングをサポートした最初のコンピューターであり、仮想メモリの設計に大きな影響を与え、関連する研究に動機を与えました。このシステムは1958年から1962年の間に設計されました。 80386が約20年後に設計され、コンピュータ(およびそれらが実行するワークロード)がその期間中に大幅に進化したとしても、80386でサポートされるページサイズはアトラスでサポートされるページサイズにいくぶん近いことに注意してください時間!実際、その時代の多くのコンピュータは、0.5〜5 KBの範囲のページサイズを使用していました。当時の研究者たちは、仮想メモリシステム(ページングとセグメンテーション)の研究にかなりの労力を費やしていました。
大きな疑問の1つは、次のとおりです。最適なページサイズは何ですか。 60年代と70年代には、アプリケーションのパフォーマンスに対するページサイズの影響を調査および理解し、ページサイズの選択方法に関する推奨またはガイドラインを提供する多数の作品が発表されました。決して出版されなかった多くの論文が確かにあります。私の知る限り、これには「...したがって、ページサイズは4 KBにする必要がある」というIntelのドキュメントが含まれています。しかし、ページサイズに影響を及ぼしたり相互作用したりする要因、およびページサイズ(または、複数のページサイズ)を選択するプロセスはよく知られています。これについては、この回答で基本的なレベルで説明します。特に、4 KBのページサイズが妥当である理由についても説明します。
ページング方式では、物理メモリは、同じサイズのページフレームと呼ばれる一連の連続したメモリ領域として編成されます(これはページングの定義的な特徴です)1)。各ページフレームは、仮想ページと呼ばれる仮想アドレススペースの同じサイズのチャンクにマッピングできます。
ページがN
バイトで構成されると仮定します2 (これは、ページフレームのサイズも定義によりN
バイトであることを意味します)、P
ページで構成される仮想アドレス空間を考慮します(つまり、ページ番号は{0、1、2です) 、...、P
-1}、仮想アドレスの総数はN
* P
)です。また、物理アドレス空間がF
ページフレームで構成されているとします(つまり、ページフレーム番号は{0、1、2、...、F
-1}であり、物理アドレスはN
* F
)です。
仮想アドレスVA
が与えられた場合、物理アドレスPA
を決定するメカニズム(a mapping device)が必要です。それがマップされているか、ページフォールトがマップされなかった場合に発生します。マッピングデバイスは、どこかに格納されているデータ構造(ページテーブル)を使用してマッピングを実行します。割り当てられた仮想ページごとに、そのテーブルに、ページのマッピング方法と、場合によってはいくつかの追加の属性(保護属性など)を説明するエントリがあるはずです。ご覧のとおり、ページテーブルエントリのデザインはページサイズと相互作用します。 Intel 80386のページテーブルエントリのデザインについては後で説明します。
仮想アドレスのサイズはログです2(N
* P
)および物理アドレスのサイズはログです2(N
* F
)。 VA
の一部のビットはページ内のオフセットを表し、他のビットはマッピングデバイスを使用してページを識別するページ番号を表します。
ページサイズにはいくつのオプションがありますか?まあ、それはN
* P
またはN
* F
のいずれか小さい方まで、1バイト程度です。それはたくさんの選択肢です。
仮想アドレスVA
は、ページ番号とオフセットのペア(PN
、OFF
)と同等です。翻訳プロセスは可能な限り効率的である必要があります。プログラマーにとって便利です3 ページ内のバイトをアドレス空間で連続させる。このようにして、マルチバイトデータ構造内のアイテムのアドレスは、データ構造のベースアドレスを構成する単一のアドレスに対して単純な計算で計算できます。これは、最下位のログを使用して実現できます2(N
)オフセットを表す仮想アドレスのビット(切り上げ)およびページ番号を表す残りのビット。
N
が2の累乗でない場合、これらのビットの値に応じて、オフセットとページ番号の間で共有されるいくつかのビットがあります。 N
を2の累乗にすることで、このような複雑な問題は発生しません。したがって、2の累乗のページサイズを使用するのが適切です。ページングをサポートするすべての実際のプロセッサは、2の累乗のページサイズを使用します(ただし、アドレス可能度の単位は8ビットではない場合があります)。しかし、正直なところ、これが本当に重要かどうかは明らかではありません。今日のテクノロジーを使用すると、N
が2の累乗であるかどうかは、パフォーマンスやその他の関心のある指標に測定可能な影響を与えない場合があります。実際、将来的にページサイズがますます大きくなるにつれて、2の累乗ではないページサイズの方が適している場合があります。しかし、これまでのところ、これは起こっていません。ここで私がしようとしているポイントは、ページサイズを2の累乗ではないようにするデザインオプションが自動的に閉じられるべきではないということです。これは将来の仮想メモリシステムの研究の良い機会だと思います。
とにかく、4 KBページの選択は80年代に行われたことを念頭に置いて、ページサイズのそのような非常に小さな変動は(理論的にも実験的にも)重要性が低いことが示されました。したがって、2のべき乗のページサイズの利便性が勝利しました。これにより、ページサイズの数が減少し、指数関数的に考慮されます。しかし、私たちはまだ十分な範囲のオプションを持っています。
マッピングデバイスはページのレベルで機能するため、オペレーティングシステムから見た割り当ての単位は仮想ページです。4。アプリケーションが1バイトのみを割り当てる必要がある場合でも、仮想ページ全体をその1バイトに割り当てるようにOSに指示する必要があります。この問題は内部断片化と呼ばれます。各アプリケーション(またはアプリケーションの各コンポーネント)には、ページサイズのチャンクでメモリを割り当てる独自の仮想アドレス空間があります。各アプリケーションでは、割り当てる単一のオブジェクトに単一のページを使用せず、より多くのページを割り当てる前に、同じページからできるだけ多くのオブジェクトを割り当てることが期待されています。ただし、ページ属性はページのレベルで機能するため、同じアプリケーションが複数のユーザーモードメモリマネージャーを使用する場合があり(複数のC/C++ランタイムを使用する場合など)、アプリケーションが使用していないページの一部を共有することは困難です。他のアプリケーションでは、システムの多くのページで内部断片化が発生する可能性があります。ページサイズを小さくすると、無駄な物理メモリ(システム全体)と仮想メモリ(プロセスごと)の量を減らすことができます。
さらに、通常、アプリケーションはその存続期間を通じて多くのフェーズを経て、フェーズごとに異なるメモリ要件を示します。ページサイズがたとえば16 KBであるが、多くのアプリケーションが多くのフェーズで10 KBしか必要としない場合、多くの無駄な物理メモリが存在し、メモリ不足の状況につながる可能性があります。 8または4 KBなどのより小さなページサイズがサポートされている場合は回避されました。
ページが小さいほど、コピーの作成にかかる時間が短くなるため、コピーオンライトソフトページフォールトを処理するには、ページサイズを小さくすることが推奨されます。非常に小さいページサイズの場合、メモリバスの帯域幅によっては、測定可能な違いが生じない場合があります。
70年代のコンピューターで利用可能な物理メモリの一般的な量は、10〜100 KBの範囲でした。数百KB以上のページサイズを用意しても意味がありません。実際、当時のアプリケーションのワーキングセットは、通常、ほんの数KBまたは数十KBでした。したがって、使用可能なすべての物理メモリを消費するのは数ページのみであるため、16 KBのページサイズでも実用的であるとは考えられません。ページサイズは、物理メモリの量と一致している必要があります。もちろん、この議論は今日のシステムにも適用できます(たとえば、128 GBのページを用意しても意味がありません)。
したがって、ワーキングセットのサイズと 70年代と80年代前半 の物理メモリの可用性を考慮すると、ページサイズは範囲2の2の累乗である必要があります。-214。いいですね、今では15のオプションから選択できます。
また、ページサイズが大きいほど良いと主張することもできます。同じワーキングセットの場合、ページサイズが小さいと、アプリケーションごとのページ数が多くなるため、変換を有効にするためにページテーブルエントリが必要になります。これには基本的に、ページテーブルの構造に関係なく、より大きなページテーブルが必要です(ただし、正確なオーバーヘッドは、後で説明するページテーブルエントリ自体の設計によって異なります)。たとえば、4バイトのページと数十KBの一般的なワーキングセットがあるとします。次に、物理メモリのほとんどは、実際にはデータではなくページテーブルを保持するために割り当てられます。ページテーブルをセカンドストレージにページングすると、個々のメモリ参照で二重ページフォールトが発生します。これはパフォーマンスにとって絶対にひどいものです。そのようなデザインは明らかにばかげています。
基本的に、ページサイズは、可能な限り最小のワーキングセットサイズよりも(はるかに)小さくてはなりません。これはすぐにサイズ2のページを除外します-26、8つのオプションを残します。ページサイズを研究する70年代と80年代前半の論文は、これらの8つのオプションのみを研究しています。
大きなページサイズが有利になる別の理由があります。仮想メモリの利点の1つは、揮発性データを保持するためにメインメモリに加えてセカンダリストレージを透過的に使用できることです。ただし、二次記憶装置は機械的であり、バルク転送で最高のパフォーマンスを発揮します。これは実際にはガイドラインの詳細であり、ページサイズを除外するべきではありません。さまざまなデザインと特性を持つデバイスがあり、最終的に、バルク転送のパフォーマンス上の利点はある時点で飽和します。ただし、ページサイズがパフォーマンスに与える影響を測定する際には、この点を考慮する必要があります。検討されているアプリケーションのタイプが空間的な局所性をほとんど示さない場合でも、ディスクとの間で余分なバイトをコピーすることは完全に無料ではないため、ページサイズは小さい方が望ましいでしょう。
参照の空間的な局所性により、特定のページサイズの使用が奨励されます。非常に小さいページサイズの場合、ページ内のすべてのバイトが短期間に使用される可能性が高いです。ページのサイズが大きくなると、使用される可能性が低いバイト数が増加します。ただし、非常に大きなページの場合、局所性に関係なく、すべてのワーキングセットが少数のページに収まる場合があります。したがって、ページフォールトの数を最小限に抑えるには、ページサイズが小さすぎるか、または大きすぎる必要があります。しかし最終的には、これはアプリケーションごとに異なります。オブジェクト指向プログラミングや関数型プログラミングなどの新しいプログラミングパラダイムやマルチスレッドなどの手法では、リンクされた構造が広範囲に使用されたり、さまざまなアプリケーションが相互にやり取りしたりする方法により、実際に空間的な局所性が低下する場合があります。ページフォールトの数を減らすには、ページサイズを大きくすることをお勧めします。ただし、ページサイズを小さくすると、複数のアプリケーション間で共有されるメモリの方が、共有ページの内部断片化を減らすのに適している場合があります。また、メインメモリに保持できるページフレームの数はページフォールトの数と相関しているため、ページサイズが小さい方が好ましいことが実験的に示されています。
当時、TLBの必要性はよく認識されていました。インテルはそれらを特許と呼んでいたページキャッシュ(インテルがその用語を最初に使用したかどうかは不明)。アドレス変換は命令の実行のクリティカルパス上にあるため、高速TLBは非常に重要です。それらをできるだけ高速にするには、それらを小さくする必要がありますが、少数のページテーブルエントリしかキャッシュできません。これにより、より大きなページサイズを使用することができます。
最適なページサイズを検索したところ、ページサイズがないことがわかりました。当時は、複数のページサイズをサポートする必要があることがわかっていました。実際、1965年に設計されたMulticsシステムは64または1,024ワードのページをサポートしました(ワードのサイズは36ビットです)。範囲2のページサイズ7-214 さまざまなシナリオで、経験的および理論的に最適であることが示されました。 インテルは、4KBのページにより、80年代に顧客が使用したアプリケーションの平均パフォーマンスが最高になることを確認していたはずです。今日のコンピューターとアプリケーションでは、ページサイズのこのような小さな違いは、70年代と80年代にあったため、それほど大きな違いはありません。
ページディレクトリエントリとページテーブルエントリの設計については、Intel 特許 で詳しく説明しています。ページテーブルエントリのサイズとページテーブルの全体的な構造は、ページサイズに関する多くの調査で考慮されているため、これらはすべて相互作用するため、これは重要です。回答を短くするために、これについては詳しく説明しません。
Intelは 特許 を数ヶ月前に許可されました。これは明らかに64 KBのデフォルトページサイズを持つシステムを提案しますが、同時に4 KBページ(および他のIA-32eページサイズ)をサポートします下位互換性のため。私は特許から引用します:
64 KBページの4 KBサブページへのマッピングをサポートした結果、VA64は、4 KBページごとの独立した保護ビットや任意の4 KBに整列したアドレスマッピングなど、4 KBページで現在定義されているすべての操作を直接サポートします。 VA64は、OSカーネルが64 KB単位でメモリを割り当てる場合でも、4 KB境界でのOSカーネルページ管理もサポートします。ラージページのサポートの結果として、VA64は、仮想アドレス範囲のすべての分割を、Intel CorporationのIA-32eページングシステムなどの既存のページングシステムがサポートするページにサポートします。したがって、VA64は、4 KBページのWindows®OSカーネルで動作するアプリケーションとハードウェアデバイスをサポートし、64 KBページを使用できる場合は64 KBページを最大限に活用します。
VA64の機能は、第1世代のVA64対応OSカーネルですべてサポートする必要はなく、OSカーネルで段階的に採用できます。たとえば、VA64対応のOSカーネルは、すべてのページを現在のサイズ(たとえば、4 KB/2 GB/1 TB)にマッピングしますが、新しいページテーブル形式に変更します。ページテーブル形式の変更後、OSカーネルを変更して、仮想メモリを64 KB単位でマップし、64 KBページを空きリストに格納するように変更できます。その後、OSカーネルは64 KBの使用を開始できます。配置と保護が許可する場合は常にページングし、他のVA64機能のサポートを追加します。
VA64ページングシステムについては、特許に記載されているもの以外は何も知りません。インターネット上のどこにも何もありません。もっとすぐにわかると思います。
デニング、P.J。(1970)。 仮想メモリ 。 ACM Computing Surveys Volume 2 Issue 3、153-189。
Gelenbe、E.、Tiberio、P.&Boekhorst、J. C. A.(1973)。 デマンドページングシステムのページサイズ 。 Acta Informatica、3(1)、1-23。
Alanko、T. O.&Verkamo、A. I.(1983)。 セグメンテーション、ページング、仮想メモリ内の最適なページサイズ 。パフォーマンス評価、3(1)、13-33。
Corbató、F。J.、およびVyssotsky、V。A.(1965)。 Multicsシステムの紹介と概要 。 1965年11月30日-12月1日の議事録で、秋の合同コンピューター会議、パートI(pp。185-196)。
(1)実際には、単一の仮想ページのサイズは、ページフレームのサイズの倍数になる可能性がありますが、そこには行きません。
(2)公式を一般化し、「ワード」という用語を使用して、バイトではなくメモリのアドレス可能な最小単位を指すことができますが、ここでは重要ではありません。
(3)プログラミング言語によっては、プログラマーではなく、コンパイラー、リンカー、アセンブラー、およびバイナリー・コードを処理するツール。
(4)ページングと非ページングの同時使用をサポートするシステムを設計することは確かに可能です。それにより、複数の割り当て単位をサポートする可能性がありますが、そこには行きません。
私はウィキペディアの記事からこれを得て、引用します:
ページサイズは通常、プロセッサアーキテクチャによって決定されます
以下の記事をご覧ください。
Sleepsortの計算は非常に興味深いので、この回答/コメントを追加します。これは、Webページに追加する必要があります(もちろん、ソースを記載します)。プログラムでページサイズを計算する方法に関する質問への(可能な)回答は here にあります。スリープソートで述べられているように計算される方法は非常に興味深いです。 x86_64についても同じことを行いましたが、期待した結果が得られませんでした。ただし、 メモリ管理x86_64 についてさらに読むと、64ビットのIntelでは16ビットが使用されておらず、計算するために48ビットのままにしておくことがわかりました。メモリツリーの分岐用の9ビットは、それぞれがさらに9ビット分岐します。ここでは、分岐用にさらに9ビット、最後に最後の分岐の葉用に9ビットです。つまり、メモリページの各アドレスに対して48-36 = 12ビットです。 2 ^ 12 = 4096は前にスリープソートで述べたように。スリープソートの計算に従って、このアーキテクチャのパス数は3または4(だれかがそれを説明できる場合)だと思います。
2^x * 2^x * 2^x * 2^x * 2^y = 2^48
4x + y = 48
this time we have 8 bytes for each address (8 bytes * 8 bits / byte = 64 bits)
2^y / 2^3 = 2^x
y - 3 = x
filled in in previous equation:
4(y - 3) + y = 48
4y - 12 + y = 48
5y = 60
y = 12
because 2^y represents the pagesize, the size = 2^12 = 4096 bytes
「Linuxの巨大なページについてはどうですか」という質問を私に残してください。