古いLinuxカーネルがプリエンプティブでない理由は何ですか?


15

最初のLinux開発者は、なぜプリエンプティブでないカーネルの実装を選択したのですか?同期を保存するためですか?

私の知る限り、Linuxは90年代前半に開発されました。PCには単一のプロセッサが搭載されていました。そのようなPCにおいて、プリエンプティブでないカーネルはどのような利点がありますか?しかし、マルチコアプロセッサによって利点が減るのはなぜですか?

回答:


25

Linuxカーネルのコンテキストでは、人々がプリエンプションについて話すとき、彼らはしばしばカーネル自体を中断する能力を指します-基本的に、カーネルコードの実行中にタスクを切り替えます。これを可能にすることは非常に複雑です。これがおそらく、カーネルがプリエンプティブにされるのに長い時間がかかった主な理由です。

それは大きなカーネルロックで保護されているため、最初はほとんどのカーネルコードを中断できませんでした。そのロックは、ますます多くのカーネルコードから次第に削除され、並行してカーネルへの複数の同時呼び出しが可能になりました(SMPシステムが一般的になるにつれて、これはより重要になりました)。しかし、それでもカーネル自体をプリエンプティブにできませんでした。それはさらに開発を続け、PREEMPT_RT最終的にメインラインカーネルにマージされたパッチセットで頂点に達しました(とにかくBKLをプリエンプトすることができました)。現在、カーネルは、スループットとレイテンシーの特性に応じて、多かれ少なかれプリエンプティブに設定できます。詳細については、関連するカーネル構成を参照してください。

カーネル構成の説明からわかるように、プリエンプションはスループットとレイテンシに影響し、同時性には影響しません。シングルCPUシステムでは、プリエンプションはイベントをより短い反応時間で処理できるため、依然として有用です。ただし、(カーネルはタスクの切り替えに時間を費やすため)スループットも低下します。プリエンプションにより、単一または複数のCPUシステム内の任意のCPUが、より迅速に別のタスクに切り替えることができます。マルチCPUシステムの制限要因はプリエンプションではなく、大きなロックなどのロックです。コードがロックを取得するたびに、別のCPUが同じアクションの実行を開始できないことを意味します。


11

プリエンプティブカーネルは、ビッグカーネルロックがないことを意味します。

Linuxには、最初の瞬間からプリエンプティブマルチタスクがありました(つまり、ユーザーコードはプリエンプティブでした)(LinusがFunet ftpサーバーにアップロードした非常に最初のLinux 0.0.1は、すでにプリエンプティブマルチタスクでした)。たとえば、複数の圧縮またはコンパイルプロセスを実行した場合、それらは最初の瞬間から並行して実行されました。

-当時-広く使用されているWin31に反して。Win31では、タスクが「カーネル」からCPUを取得した場合、デフォルトでOS(または他のタスク)に制御を戻すタイミングを決定するのはその責任でした。プロセスがこの機能を特別にサポートしていない場合(追加のプログラミング作業が必要)、実行中に他のすべてのタスクが中断されました。Win31に統合されたほとんどの基本的なアプリでもそのように機能しました。

プリエンプティブマルチタスクとは、タスクが必要に応じてCPUを割り当てる方法がないことを意味します。代わりに、タイムスロットが期限切れになると、カーネルはCPUをそれらから解放します。したがって、プリエンプティブオペレーティングシステムでは、不適切に記述されたプロセスまたは機能が不十分なプロセスがOSをフリーズしたり、他のプロセスの実行を回避したりすることはできません。Linuxは常にユーザー空間プロセスを先取りしていました。

ビッグカーネルロックとは、場合によっては、カーネルスペース内にロックが存在し、他のプロセスが保護されたコードを実行できないことを意味します。たとえば、複数のファイルシステムを同時にマウントすることはできません。複数のマウントコマンドを指定した場合、Big Kernel Lockを割り当てるためにマウントする必要があるため、それらは引き続き連続して実行されました。

カーネルをプリエンプティブにするには、この大きなカーネルロックを削除する必要がありました。つまり、マウントとその他のタスクを同時に実行できるようにしました。それは大きな仕事でした。

歴史的に、これはSMPのサポートの増加(マルチCPUサポート)によって非常に緊急に行われました。初めて、実際にはマルチCPUメインボードがありました。後に複数のCPU(「コア」)が単一のチップに統合されましたが、今日では、実際にマルチCPUのマザーボードはすでにまれです(通常、高価なサーバーシステムにあります)。また、実際にシングルコアシステム(単一のコアを持つ単一のCPUのみが存在する場合)もまれです。

したがって、あなたの質問に対する答えは、「先制的ではない理由」ではありません。なぜなら、それは常に先制的だったからです。本当の問題は、プリエンプティブカーネルの実行が本当に必要な理由です。その答えは、メニーCPU、メニーコアシステムの比率の増加です。


私は実際には理解していませんでした:(カーネルバージョン2.4までは、ユーザープロセスのみがプリエンプティブであり、カーネルはプリエンプティブではありませんでした。シングルコア・プロセスの実装あなたはどう思いますか。?
Narden

@Nardenあなたがそれを読んだかどうかはわかりません。1.3または2.0までは、複数のプロセスが実行されていたとしても、カーネルスペースに存在できるプロセスは1つだけでした。この制限は2.0でほぼ解消されました。2.4までは、ビッグカーネルロックがありました(つまり、複数のファイルシステムを同時にマウントすることはできませんでした)。
peterh -復活モニカ

@Nardenしかし、これは協調的なマルチタスクではなく、意図的にCPUをタスクスケジューラに戻すプロセスは必要ありませんでした。はい、BKLの理由は、これを正しく行うには多くの作業が必要である可能性が高いことです:1)ロックを分割する必要がある2)ロックフリーのデータ構造を使用する必要がある場合3)分割されたロックがデッドロック/ライブロック、これらは通常、特に汚い、修正が難しいバグです。それらをすべて見つけて修正する必要があります4)すべてのドライバーをカーネルコアAPIの変更に移植する必要があります。
peterh -復活モニカ

回答を探しているときに読みました。また、私が受講しているコース(オペレーティングシステム)の情報としても提供されています。
ナーデン

1
Big Kernel Lockは、カーネルで実行されているときに他のスレッドがカーネルに入るのを防ぎました。カーネルは対称マルチプロセッシングを念頭に置いて最初から設計されていないため、1つのスレッドのみが許可されました。ただし、プリエンプティブカーネルとは何か違うことを意味します。従来、実行コンテキストは、カーネルがユーザー空間に戻ったときにのみ変更されました。プリエンプティブカーネルでは、実行中のカーネルコードの途中でスレッドを横取りできます。
ヨハンMyréen17年

3

これは技術的な答えではなく、OPが提起した特定の質問に対する歴史的な答えです。「古いLinuxカーネルのプリエンプティビティがない理由は何ですか?」

(私は、彼の答えとコメントで@peterhによって説明されているように、「非プリエンプティビティ」によってOPは1つのユーザープロセスのみがカーネル内(API内)にあるという事実のいずれかまたは両方を指していると仮定します時間および/またはビッグカーネルロック。)

Linus Torvaldsはオペレーティングシステムがどのように機能するかを学ぶことに興味があり、彼が学んだ方法はそれを書くことでした。彼のモデル、ベース、および初期開発環境はMinixでした。教育目的のための既存のOS(つまり、運用OSではありません)は無料ではありませんでした(当時のオープンソースのように-ビールのように無料ではありませんでしたが、どちらか)。

だから彼はプリエンプションなしでカーネルを書いた(他の回答で言及されているビッグカーネルロック)それはあなたが新しいOSを教育目的のために迅速に立ち上げて実行したい場合にそれを行う方法だからです:それははるかにはるかに簡単です。ユーザープログラムとデバイスの同時マルチプログラミングをサポートするカーネルは十分困難です- カーネル自体を並行にすることは非常に困難です。

彼がLinuxの人気/有用/重要性を知っていたら、おそらく同じ方法でそれを行っていたでしょう。(IMOのみ、私は彼が実際に何を考えているのか分かりません。)走る前にあなたは歩かなければならないからです。

そして、a)現在のLinux(または当時のLinux)を作成するために他に多くの作業を行う必要があり、b)変更することは大きな困難な仕事であるため、それは長い間そのようにとどまりました(他の回答で説明されているように)。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.