ホームページ  >  記事  >  システムチュートリアル  >  Linux カーネルの深い理解: 仮想アドレス空間と物理メモリ間のマッピング関係

Linux カーネルの深い理解: 仮想アドレス空間と物理メモリ間のマッピング関係

WBOY
WBOYオリジナル
2024-06-03 09:28:441015ブラウズ

ビデオメモリマッピング

化学メモリは、アドレス指定可能なダイナミック ランダム アクセス メモリ (DRAM) と総称されます。カーネルのみが数学メモリに直接アクセスできます。

Linux カーネルはプロセスごとに独立した仮想アドレス空間を提供しますが、このアドレス空間は連続的です。このようにして、プロセスはビデオ メモリ、より正確には仮想ビデオ メモリに簡単にアクセスできます。仮想アドレス空間の内部は、カーネル空間とユーザー空間の 2 つの部分に分かれています。

linux 用户分配空间_linux磁盘分配空间_linux分配用户权限

プロセスがユーザー モードの場合はユーザー空間メモリにのみアクセスでき、カーネル モードに入った後にのみカーネル空間メモリにアクセスできます。実際、各プロセスのアドレス空間にはカーネル空間が含まれていますが、このカーネル空間は同じ化学メモリ、つまり共有ダイナミック リンク ライブラリ、共有グラフィックス メモリなどに関連付けられています。プロセスがカーネル状態に切り替わると、カーネル空間メモリに簡単にアクセスできます。

すべての仮想メモリがケミカル メモリに割り当てられるわけではありません。ただし、割り当てられたケミカル メモリはメモリ マッピングによって管理されます。ビデオ メモリ マッピングは、仮想ビデオ メモリ アドレスを化学的ビデオ メモリ アドレスにマッピングすることです。ビデオ メモリ マッピングを完了するために、カーネルはプロセスごとにページ テーブルを維持し、仮想アドレスとケミカル アドレス間のマッピング関係を記録します。

linux磁盘分配空间_linux分配用户权限_linux 用户分配空间

ページ テーブルは実際には CPU のビデオ メモリ管理ユニット MMU に保存されており、通常の状況では、プロセッサはハードウェアを介してアクセスするビデオ メモリを直接見つけることができます。プロセスによってアクセスされた仮想アドレスがページ テーブルで見つからない場合、システムはページ フォールト例外を形成し、カーネル空間に入ってケミカル メモリを割り当て、プロセス ページ テーブルを更新し、最後にユーザー空間に戻ってプロセスを再開します。プロセスの操作。

CPUコンテキストスイッチングにおけるTLB(TranslationLookasideBuffer、TranslationLookasideBuffer)は、MMU内のページテーブルのキャッシュです。プロセスの仮想アドレス空間は Linux システムとは独立しており、TLB アクセス速度は MMU よりもはるかに速いため、プロセスのコンテキスト切り替えと TLB リフレッシュの数を減らすことで、TLB キャッシュの使用量を減らすことができます。これにより、CPU のメモリアクセスパフォーマンスが向上します。

MMU はビデオ メモリ マッピングの最小単位を指定します。これはページであり、通常はサイズが 4KB です。このように、各ビデオ メモリ マッピングは 4KB または 4KB の整数倍のビデオ メモリ空間に関連付ける必要があります。

4KB ページでは、ページ テーブル全体が非常に大きくなります。たとえば、32 ビット システムでは 4GB/4KB = 100 万ページ テーブル エントリを超えます。ページ テーブル エントリが多すぎる問題を解決するために、Linux は 2 つのメカニズム、つまりマルチレベル ページ テーブルとヒュージ ページ (HugePage) を提供します。

linux分配用户权限_linux 用户分配空间_linux磁盘分配空间

マルチレベルページテーブルとは、ビデオメモリをブロックに分割して管理し、ブロックインデックスとブロック内のスキューに対する本来のマッピング関係を変更するものです。通常、仮想ビデオ メモリ空間のごく一部のみが使用されるため、マルチレベル ページ テーブルは使用中のブロックのみを保存し、ページ テーブル エントリの数を大幅に削減できます。 Linux は 4 レベルのページ テーブルを使用してビデオ メモリ ページを管理し、最初の 4 つのエントリはページの選択に使用され、最後のインデックスはページ内のスキューを示します。

linux 用户分配空间_linux磁盘分配空间_linux分配用户权限

ラージ ページは、通常のページよりも大きなビデオ メモリ ブロックです。一般的なサイズは 2MB と 1GB です。ラージ ページは通常、Oracle、DPDK など、大量のビデオ メモリを使用するプロセスで使用されます。

このメカニズムを通じて、ページテーブルのマッピングの下で​​、プロセスは仮想アドレスを介して数学メモリにアクセスできます。

仮想ビデオメモリ空間の分配

上部はカーネル空間、下部はユーザー空間のメモリであり、ユーザー空間は複数の異なるセグメントに分割されています

linux磁盘分配空间_linux分配用户权限_linux 用户分配空间

ユーザースペースビデオメモリには、低から高まで5つの異なるビデオメモリセグメントがあります

1. コードや定数などを含む読み取り専用セクション。

linux磁盘分配空间_linux 用户分配空间_linux分配用户权限

2. パノラマ変数などを含むデータセグメント

3. 動的に割り当てられたビデオメモリを含むヒープは、低いアドレスから始まり、下に向かって減少します

4. ダイナミック ライブラリ、共有ビデオ メモリなどを含むファイル マッピング セグメントは、高いアドレスから始まり、上に向かって減少します

5. ローカル変数や関数呼び出しコンテキストなどを含むスタック。スタックのサイズは固定で、通常は 8M です

これら 5 つのビデオ メモリ セグメントのうち、ヒープとファイル マップされたビデオ メモリは動的に割り当てられます。たとえば、C 標準ライブラリの malloc または mmap() を使用すると、ヒープとファイル マップされたセグメントにそれぞれビデオ メモリを動的に割り当てることができます。 64 ビット システムのビデオ メモリ分布は似ていますが、ビデオ メモリ空間ははるかに大きくなります

ビデオメモリの割り当てとリサイクル

malloc() は C 標準ライブラリが提供するビデオメモリ割り当て関数で、システムコールに対応して brk() と mmap() の 2 つの実装メソッドがあります。

linux磁盘分配空间_linux 用户分配空间_linux分配用户权限

ビデオ メモリの小さなブロック (128K より大きい) の場合、C 標準ライブラリは brk() を使用して割り当てます。つまり、ビデオ メモリはヒープの先頭位置を接続することによって割り当てられます。この種のビデオ メモリは、解放された後すぐにはシステムに返されませんが、再利用できるようにキャッシュされます。

linux磁盘分配空间_linux分配用户权限_linux 用户分配空间

ビデオ メモリの大きなブロック (128K 未満) の場合は、ビデオ メモリ マッピング mmap() を直接使用して割り当てます。つまり、ファイル マッピング セクションで空きビデオ メモリを見つけて割り当てます。

これら 2 つの方法の類似点と相違点:

brk() メソッドのキャッシュにより、ページ フォールト例外の発生が減り、ビデオ メモリ アクセスの効率が向上します。ただし、この種のビデオ メモリはシステムに返されないため、ビデオ メモリがビジー状態になると、ビデオ メモリの割り当てと解放が頻繁に行われ、ビデオ メモリの断片化が発生します。

mmap() メソッドで割り当てられたビデオメモリは解放時にシステムに直接返されるため、mmap が発生するたびにページフォールト例外が発生します。ビデオ メモリがビジー状態の場合、ビデオ メモリの割り当てが頻繁に行われると、多数のページ フォールト例外が発生し、カーネルの管理負担が軽減されます。これは、malloc がビデオ メモリの大きなブロックに対してのみ mmap を使用する理由でもあります。

これら 2 つの呼び出しが発生する場合、ビデオ メモリは実際には割り当てられないことに注意してください。この種のビデオ メモリは、最初にアクセスされたとき、つまりページ フォールト例外を通じてカーネルにアクセスされたときのみ割り当てられ、その後、カーネルがビデオ メモリを割り当てます。

一般に、Linux はバディ システムを使用してビデオ メモリの割り当てを管理します。上で述べたように、この種のグラフィックスは MMU でページ単位で管理され、パートナー システムもグラフィックス メモリをページ単位で管理し、隣接するページを結合することでグラフィックス メモリの断片化を軽減します。 brk メソッドによって引き起こされるビデオ メモリの断片化)。

しかし、実際のシステム動作では、1K 未満など、ページよりも小さいオブジェクトが多数存在します。それらに個別のページが割り当てられると、大量のビデオ メモリが無駄になります。

ユーザー空間 Linux ユーザー割り当て空間 では、brk() を介して malloc によって割り当てられたビデオ メモリは、解放されてもすぐにはシステムに返されず、キャッシュされて再度使用されます。

カーネル空間では、Linux はスラブ アロケーターを通じて小さなビデオ メモリを管理します。スラブは、パートナー システム上に構築されたキャッシュと考えることができます。その主な機能は、カーネル内の小さなオブジェクトの割り当てと解放です。

linux 用户分配空间_linux磁盘分配空间_linux分配用户权限

ビデオ メモリのリサイクル: ビデオ メモリの場合、解放せずに割り当てだけを行うと、ビデオ メモリのリークが発生し、システム ビデオ メモリを使い果たすこともあります。したがって、アプリケーションはビデオ メモリを使い果たした後も、free() または unmap() を呼び出して未使用のビデオ メモリを解放する必要があります。実際、システムはプロセスがすべてのビデオ メモリを使い果たすことはありません。ビデオ メモリが不足していることが判明した場合、システムは、次の 3 つの形式などの一連のメカニズムを使用してビデオ メモリを再利用します。

(1) キャッシュをリサイクルします。たとえば、LRU (LeastRecentlyused) アルゴリズムを使用して、最も最近使用されていないビデオ メモリ ページをリサイクルします。

(2) アクセス頻度の低いビデオ メモリをリサイクルし、スワップ パーティション (Swap) を介して、使用頻度の低いビデオ メモリを C ドライブに直接転送します。ただし、Swap は C ドライブの領域の一部をビデオ メモリとして使用します。プロセスによって一時的に使用されていないデータを C ドライブに保存できます (このプロセスはスワップアウトと呼ばれます)。プロセスがこれらのビデオ メモリにアクセスすると、このデータを C ドライブからビデオ メモリに読み取ることができます (このプロセスはスワップアウトと呼ばれます)。スワッピングインと呼ばれます)。スワップによりシステムの利用可能なビデオ メモリが増加しますが、通常、スワップはビデオ メモリが不足している場合にのみ発生します。また、C ドライブの読み取りおよび書き込み速度はビデオ メモリの速度よりもはるかに遅いため、スワップはビデオ メモリのパフォーマンスに深刻な影響を及ぼします。問題。

(3) プロセスを強制終了します。ビデオ メモリが不足している場合、システムは OOM (OutofMemory、カーネルの保護メカニズム) を通じて、大量のビデオ メモリを占有しているプロセスを直接強制終了します。 OOM はプロセスのメモリ使用量を監視しますが、oom_score を使用して各プロセスのメモリ使用量をスコアリングします。

プロセスによって消費されるグラフィックス メモリが大きいほど、oom_score も大きくなります。

プロセスが占有する CPU が増えるほど、oom_score は小さくなります。

このように、プロセスの oom_score が大きいほど、より多くのビデオ メモリが消費され、OOM によって強制終了されやすくなり、システムの保護が強化されます。

実際、実際の作業ニーズに応じて、管理者は /proc ファイル システムを通じてプロセスの oom_adj を自動的に設定し、プロセスの oom_score を調整できます。 oom_adj の範囲は [-17,15] です。値が大きいほど、プロセスは OOM によって強制終了されやすくなります。値が小さいほど、プロセスは OOM によって強制終了されにくくなります。は固く禁止されています。次のコマンドを使用すると、sshd プロセスの oom_adj を -16 に減らすことができ、sshd プロセスが OOM によって簡単に強制終了されなくなります。

echo-16>/proc/$(pidofsshd)/oom_adj

linux磁盘分配空间_linux 用户分配空间_linux分配用户权限

linux磁盘分配空间_linux 用户分配空间_linux分配用户权限

バッファとキャッシュ

free コマンドのバッファとキャッシュはどちらもキャッシュを意味しますが、用途は異なります

1. バッファーはカーネルバッファーによって使用されるビデオメモリであり、/proc/meminfo のバッファー値に対応します

2. キャッシュは、カーネル ページ キャッシュとスラブによって使用されるビデオ メモリであり、/proc/meminfo の Cache と SReclaimable の合計に相当します。

簡単に言うと、Buffer は C ドライブのデータのキャッシュであり、Cache はファイル データのキャッシュであり、読み取りリクエストと書き込みリクエストの両方で使用されます。

キャッシュ(キャッシュ)は、私たちが通常目にする一次キャッシュ、二次キャッシュ、三次キャッシュなど、CPUとビデオメモリ間のデータ交換速度を高めるためにCPUの観点から設計されています。プログラムを実行するために CPU によって使用される命令とデータはすべてビデオ メモリを対象としています。つまり、ビデオ メモリから取得されます。ビデオメモリの読み書き速度が遅いため、CPUとビデオメモリ間のデータ交換速度を高めるために、CPUとビデオメモリ間のキャッシュが削減され、その速度はビデオメモリよりも速くなります

。 Linux ユーザーはスペースを割り当て、コストが高く、CPU 内にあまり多くの集積回路を統合できないため、キャッシュは通常比較的小さいです。 その後、速度をさらに向上させるために、インテルや他の企業はレベルを下げました。 2 キャッシュとレベル 5 キャッシュは、CPU の実行であるプログラムの局所性の原則に従って設計されているため、コンテンツのこのブロックをロードした後は、特定のブロックに集中します。キャッシュに保存すると、CPU がビデオ メモリにアクセスする必要がなくなるため、アクセス速度が向上します。実際、CPU が必要とするコンテンツがキャッシュ内にない場合でも、ビデオ メモリにアクセスする必要があります。

ビデオ メモリの読み取りと C ディスクの読み取りの観点から、キャッシュは、より高い読み取り効率を達成するために、再アクセスされる可能性のあるデータをキャッシュするためにより多くのビデオ メモリを使用するオペレーティング システムとして理解できます。

バッファは、ビデオメモリとハードディスク(または他のI/Oデバイス)の間のデータ交換速度を高めるように設計されています。分散した書き込み操作を一元化して、C ドライブの断片化とハード ディスクの繰り返しシークを軽減し、システム パフォーマンスを向上させます。 Linux には、バッファの内容を定期的にクリアする (つまり、C ドライブに書き込む) デーモン プロセスがあり、バッファは sync コマンドを通じて自動的にクリアすることもできます。

簡単に言えば、バッファは C ドライブに書き込まれようとしており、キャッシュは C ドライブから読み取られます。バッファはさまざまなプロセスによって割り当てられ、入力キューなどの側面で使用されます。簡単な反例は、プロセスが複数の配列を読み込む必要があることです。すべての配列が完全に読み込まれる前に、プロセスは最初に読み取った配列をバッファーに配置して保存します。

キャッシュは、C ドライブ上の I/O リクエストによく使用されます。複数のプロセスがファイルにアクセスする必要がある場合、ファイルは最後のアクセスを容易にするためにキャッシュされ、システムのパフォーマンスが向上します。

以上がLinux カーネルの深い理解: 仮想アドレス空間と物理メモリ間のマッピング関係の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。