Skip to main content.
Google custom search

NetBSD ドキュメンテーション: どのように lazy FPU コンテキストスイッチは動作するのか

どのようにlazy FPU コンテキストスイッチは動作するのかについて説明します。

Tohru Nishimura - Nara Insititute of Science and Technology

FPU ハードウェアは一般的に、現在の FPU コンテキストを保持するための ハードウェアレジスター一式を持っています。各プロセスは、 そのプロセスが実行されていない間、プロセスの状態を保持するために、 プロセス毎の予約済みのメモリー領域 (NetBSD/mips では u_pcb の中にあります) を持っています。コンテキストスイッチの度に FPU コンテキストの保存と再ロードをすることは、著しい CPU サイクルを消費します。

最近の CPU は、FP インストラクションを実行できなくする 方法を提供しています。 CPU が FP インストラクションを 実行しようとすると例外が投げられ、オペレーティングシステム は実行中のプロセスに「FPU がつかえないよ」ハンドラーの 処理を開始します。それは、プロセスが FPU を使えるように チェック、準備し、それからそのプロセスを 例外を発生させた FP インストラクションから再実行させます。今度は、 FP インストラクションは通常通りに実行され、後で他のプロセスが、この プロセスから FPU を奪うまで、「FPU が使用不可能」という状況は 発生しません。

すべてのプロセスは、FPU の所有権無しで生成され、かつ FPU の使用を 禁じられています。プロセスが FP インストラクションを実行しなけ れば、何も特別な事はおこらず、そのプロセスの実行中に FPU には手出しされません。

もし、FPU の使用を禁止されたプロセスが、FP インストラクションを 実行しようとすると、CPU は、「使用不可能」例外を投げます。グロー バルな変数 fpcurprocはどのプロセスが FPU を所有しているかを示します。 「使用不可能」例外が発生した時、FPU ハードウェアはその所有プロセスの 状況を持っています。これは、例外を投げた curproc とは異なります。 使用不可能ハンドラーは、 FPU ハードウェアコンテキストを fpcurproc の予約された領域へ保存します。そして、curproc の FPU コンテキストを FPU レジスターにロードします。プロセスの FPU コンテキストが最初 にロードされるときは、FPU 全体がクリアーされます。このように、 他のプロセスが FPU の使用を要求するまで、FPU コンテキストスイッチ は延期されます。大多数のプログラムは、 FP インストラクションを 一切実行しないため、延期された lazy FPU コンテキストスイッチは、 高コストな FPU の保存/ロードの回数を大幅に減らします。

fpcurproc が指すプロセスが終了するときに、lazy に割り当てられ ている FP context を、正しく解放するように注意しなければいけないこ とを Matt Thomas が指摘してくれました。

この厄介な FPU コンテキストスイッチシンドロームは、MMU がプロセス コンテキストスイッチに直面した時の状況に似ています。 MMU はかなり複雑なデバイスです。これは、プロセスのアドレス空間を表現す るための複雑な内部「状態」、あるいはもっと稀には、 CPU ハードウェアに 基づいて定義される、プロセスの本質と特徴(nature and feature)であるとこ ろの実行環境の「タスク表現」を保持します。いくつかの MMU には、プロセスのアドレス 空間を示すメモリー領域を指定する、専用のレジスターがあります。このような場合、 複数のメモリー領域を持ち、専用の MMU インストラクションを実行して そのレジスターを更新することでメモリー領域を切り替えることにより、 MMU コンテキストスイッチにかかるコストを下げることができます。 ある種の CPU デザインは、MMU コンテキストスイッチ のためにさわがしい見せ物のような方式をおこなうことで有名です。おどろ くべき長さの CPU サイクルを消費して、多数のレジスターを保存/ロード し、新しいプロセスの実行コンテキストを確立するためにメモリー領域をいった りきたりします。ハードウェアによるコンテキストスイッチ機能 のサポートは非常にコストが高く、実際問題めったに使われることはありません。 そして、多くの人は、それは CISC 風、あるいはシリコンの浪費だと考えています。


Back to NetBSD ドキュメンテーション: カーネル