レベル: 中級 M. Tim Jones (mtj@mtjones.com), Consultant Engineer, Emulex Corp.
2008年 4月 15日 Linux® は遅いわけでも効率性に欠けるわけでもありませんが、速いだけでは十分でない場合もあります。速さの代わりに必要となるのは、特定の許容範囲内で所定のスケジュールを確実にこなす能力です。この記事を読んで、仮想化ソリューションによく似た初期のアーキテクチャーから標準 2.6 カーネルに現在用意されているオプションに至るまで、多様なリアルタイム Linux の手法とそれぞれがリアルタイムを実現する仕組みを理解してください。
この記事では、リアルタイム特性をサポートするいくつかの Linux アーキテクチャーを紹介し、リアルタイム・アーキテクチャーとは実際に何を意味するのかについて検討します。Linux をリアルタイムに対応させるソリューションはいくつかありますが、この記事で取り上げるのはシン・カーネル (またの名をマイクロ・カーネル)、ナノ・カーネル、そしてリソース・カーネルという 3 つの方式です。そして締めくくりとして標準 2.6 カーネルのリアルタイム機能について説明し、これらの機能を有効にして使用するする方法を紹介します。
リアルタイムとその要件の定義
リアルタイム Linux アーキテクチャーを説明する準備として、以下にリアルタイムとは何かを定義します。この定義は、Donald Gillies のリアルタイム・コンピューティングに関する FAQ (「参考文献」にリンクを記載) から引用したものです。
リアルタイム・システムとは、計算の正確さが、計算の論理的正確性に依存しているのはもちろんのこと、計算結果が生成されるタイミングにも依存するシステムのことです。システムのタイミング制約に適合しない場合には、システム障害が発生したと見なされます。
これを言い換えると、システムは負荷の変化 (最小負荷から最大負荷に至るまで) にかかわらず、タイミングに即した振る舞いを保証できるよう、確定性を持っていなければならないということです。上記の定義ではパフォーマンスについては何も触れていません。その理由は、リアルタイムとは速度についての話ではなく、予測可能性についての話だからです。例えば最近の高速プロセッサーを使用した場合、Linux は一般的な割り込み応答である 20μs を達成できますが、応答時間はそれより長くなることがあります。これは Linux の速度や効率性の問題ではなく、確定性が欠けているという根本的な問題です。
いくつかの例で、一体これがどういうことなのかを説明します。まず、割り込み遅延の様子を示した図 1 を見てください。割り込みが発生すると (イベント)、CPU が実行していた処理が中断されて割り込み処理に移ります。割り込み処理では、ある程度の処理を行って発生したイベントが何であるかを判断し、さらに少し処理が行われてから、イベントを処理するために必要なタスクがディスパッチされます (コンテキスト・スイッチ)。応答時間とは、このように割り込みが発生してから必要なタスク (優先順位の最も高いタスクがディスパッチされるという前提) がディスパッチされるまでの時間のことです。リアルタイムの場合、この応答時間が確定的で、既知の最大許容時間内に収まっていなければなりません。
 |
コンテキスト・スイッチ 割り込みが発生するごとに新しいタスクをディスパッチするプロセスにはコンテキスト・スイッチが伴います。これはつまり、割り込み発生時に CPU の現行状態を保存し、その後、特定のタスクの状態を復元するというプロセスです。コンテキスト・スイッチがどんな内容になるかは、オペレーティング・システムおよび基礎となるプロセッサー・アーキテクチャーの両方によって決まります。 |
|
図 1. 割り込み遅延と応答時間
このプロセスの好例は、最近の自動車では標準装備となっているエアバッグです。自動車の衝突をレポートするセンサーが CPU に割り込みをかけた時点で、オペレーティング・システムはエアバッグを作動させるタスクを他のリアルタイム以外の処理に優先してディスパッチしなければなりません。一瞬でも作動が遅れるエアバッグなら、エアバッグが装備されていないほうがましです。
割り込み処理に確定性を与えるだけでなく、一定間隔で行われるタスク・スケジューリングもリアルタイム処理には必要です。今度は図 2 を見てください。この図には、周期タスクのスケジューリングが示されています。多くの制御システムには定期的なサンプリングと処理が必要で、システムの安定性を保つためには決められた期間 (p) に特定のタスクを実行しなければなりません。自動車のアンチロック・ブレーキ・システム (ABS) を例に挙げると、この制御システムはホイールがロックするのを防ぐため、毎秒最大 20 回の頻度で自動車の各ホイールの回転速度をサンプリングし、それぞれのブレーキの圧力を制御します。そのため、この制御システムが有効に機能するにはセンサーのサンプリングと制御を一定間隔で行う必要があります。つまり、所定の期間に他の処理に優先させて ABS タスクを実行できるようにしなければならないということです。
図 2. 周期タスクのスケジューリング
ハード・リアルタイム・システムとソフト・リアルタイム・システムの違い
処理負荷が最大の場合でも所定の期間内に必ず実行する必要のあるリアルタイム・タスクをオペレーティング・システムがサポートしている場合、そのシステムはハード・リアルタイム・システムと呼ばれますが、ハード・リアルタイムのサポートは常に必要であるとは限りません。オペレーティング・システムが平均して時間要件をサポートできる場合、そのオペレーティング・システムはソフト・リアルタイム・システムと呼ばれます。ハード・リアルタイム・システムとは、期限に間に合わないと壊滅的な結果 (例えば、エアバッグを作動するのが遅すぎたり、ブレーキ圧が長い間低下したりするなど) がもたらされる可能性のあるシステムのことです。一方、ソフト・リアルタイム・システムでは期限に間に合わなくても (1 ビデオ・フレームの損失など)、システム全体の障害になることはありません。
リアルタイムの要件を把握できたところで、次は Linux リアルタイム・アーキテクチャーをいくつか取り上げ、それぞれのアーキテクチャーがどの程度のリアルタイムをどのようにサポートするのかを見ていきます。
シン・カーネル方式
シン・カーネル (別名、マイクロ・カーネル) 方式では、ハードウェアと Linux カーネルとの間の抽象化インターフェースとして、もう 1 つのカーネルを使用します (図 3 を参照)。非リアルタイム Linux カーネルは、このシン・カーネルの優先順位の低いタスクとしてバックグラウンドで実行されます。リアルタイム以外のすべてのタスクは非リアルタイム Linux カーネルがホストし、リアルタイム・タスクはシン・カーネル上で直接実行されます。
図 3. シン・カーネル方式によるハード・リアルタイム
シン・カーネルの (リアルタイム・タスクをホストすること以外の) 主要な用途は割り込み管理です。シン・カーネルは割り込みをインターセプトし、非リアルタイム・カーネルがシン・カーネルの動作をプリエンプトできないようにします。したがって、シン・カーネルではハード・リアルタイムをサポートすることができます。
シン・カーネル方式の利点はハード・リアルタイムのサポートを標準 Linux カーネルと共存させられることですが、この方式には欠点もあります。それは、リアルタイム・タスクとリアルタイム以外のタスクがそれぞれ独立しているため、デバッグが困難になるという点です。さらに、リアルタイム以外のタスクは Linux プラットフォームで完全にはサポートされないという欠点もあります (シン・カーネルの実行が「シン」と呼ばれるのは、そのためです)。
この方式の例には、RTLinux (現在、Wind River Systems が登録商標権を所有)、RTAI (Real-Time Application Interface)、Xenomai があります。
ナノ・カーネル方式
シン・カーネル方式がタスク管理を含めて最小化したカーネルに依存しているとしたら、ナノ・カーネル方式はカーネルを最小化するという点でさらに上を行きます。その意味では、ナノ・カーネルはカーネルというより、むしろハードウェア・アブストラクション・レイヤー (HAL) に近いと言えます。ナノ・カーネルは、上位レイヤーで動作する複数のオペレーティング・システムのハードウェア・リソース共有を可能にします (図 4 を参照)。ハードウェアを抽象化するナノ・カーネルでは上位レイヤーのオペレーティング・システムに優先順位を設定できるため、ハード・リアルタイムをサポートすることができます。
図 4. ナノ・カーネル方式によるハードウェアの抽象化
ナノ・カーネル方式と仮想化方式には、複数のオペレーティング・システムを実行するという点で似ているところがあります。ナノ・カーネルの場合は、リアルタイム・カーネルと非リアルタイム・カーネルからハードウェアを抽象化しますが、これはハイパーバイザーがゲスト・オペレーティング・システムからネイティブ・ハードウェアを抽象化する方法と同様です。詳細は、「参考文献」を参照してください。
ナノ・カーネル方式の例として挙げられるのは、ADEOS (Adaptive Domain Environment for Operating Systems) です。ADEOS は同時に実行する複数のオペレーティング・システムをサポートします。ハードウェア・イベントが発生すると、ADEOS はどのオペレーティング・システムがそのイベントを処理するかを調べるため、それぞれのオペレーティング・システムに対して続けて問い合わせます。
リソース・カーネル方式
リアルタイム対応のもう 1 つのアーキテクチャーは、リソース・カーネル方式です。この方式では、各種リソースを予約するためのモジュールをカーネルに追加します。予約によって、時分割システム・リソース (CPU、ネットワーク、またはディスク帯域幅) へのアクセスが保証されます。これらのリソースには、反復期間、所要処理時間 (処理に必要な時間の長さ)、期限などの予約パラメーターがあります。
リソース・カーネルは、タスクがこれらの予約を要求できるようにするための一連のアプリケーション・プログラミング・インターフェース (API) を提供します (図 5 を参照)。この API を利用した要求は、リソース・カーネルによってマージされ、タスクで定義された制約を使ったアクセスを保証できるようなスケジュールが定義されます (保証できない場合にはエラーを返します)。EDF (Earliest-Deadline-First) などのスケジューリング・アルゴリズムを使用すれば、リソース・カーネルを使って動的なスケジューリング・ワークロードを処理することもできます。
図 5. リソース・カーネル方式によるリソース予約
リソース・カーネルの実装例としては、 移植可能なリソース・カーネルをロード可能なモジュールとして Linux に統合する CMU の Linux/RK があります。商用 TimeSys Linux/RT オファリングは、この実装から進化したものです。
標準 2.6 カーネルでのリアルタイム
今まで説明したすべての方式はアーキテクチャーとして興味深いものですが、いずれも動作の中心となるのはカーネルです。いっそのこと、標準 Linux カーネル自体にリアルタイムをサポートするために必要な変更を組み込んだとしたらどうなるでしょうか。
現在 2.6 カーネルでは、カーネルを完全にプリエンプト可能にする単純なカーネル構成によってソフト・リアルタイムの動作を実現できるようになっています (図 6 を参照)。標準 2.6 Linux カーネルではユーザー空間のプロセスが (システム・コールで) カーネルを呼び出すと、カーネルをプリエンプトすることができなくなります。つまり、優先順位の低いプロセスがシステム・コールを行った場合、優先順位の高いプロセスはその呼び出しが完了するまで CPU を利用できないため待機せざるを得ません。カーネルのこの振る舞いを変更するのが、新たな構成オプション、CONFIG_PREEMPT です。この構成オプションにより、システム・コールの途中であってもプロセスをプリエンプトして優先順位の高いプロセスを実行できるようになります。
図 6. プリエンプト可能に設定された 2.6 Linux 標準カーネル
ただし、この構成オプションにはトレードオフがあります。このオプションでソフト・リアルタイムの動作を可能にすると、オペレーティング・システムは負荷がかかっていても円滑に動作するようになりますが、それには犠牲が伴います。その犠牲とは、CONFIG_PREEMPT オプションのオーバーヘッドが追加されるため、スループットが多少低下し、カーネルのパフォーマンスも少し低下するということです。このオプションはデスクトップや組み込みシステムには役立ちますが、すべてのシナリオに適切であるとは限りません (サーバーなど)。
 |
新しい O(1) スケジューラー 2.6 カーネルの新しい O(1) スケジューラーは、大量にタスクが存在する場合でもパフォーマンスに大きなメリットをもたらします。この新規スケジューラーは、実行するタスクの数にかかわらず、限られた時間内で動作できるからです。このスケジューラーの詳細とその動作の仕組みについては、「参考文献」セクションを参照してください。 |
|
2.6 カーネルのもう 1 つの便利な構成オプションは、高分解能タイマーを対象としたものです。この新規オプションでは、タイマーを最大 1μs の分解能で動作させることが可能で (基礎となるハードウェアがサポートする場合)、赤黒木を使用した効率的なタイマー管理も実装します。赤黒木を使用すると、タイマー・サブシステムのパフォーマンス (O(log n)) に影響することなく、多数のタイマーをアクティブにすることができます。
PREEMPT_RT パッチを使用すれば、ほんのわずかな作業でハード・リアルタイムをサポートできるようになります。PREEMPT_RT パッチは、ハード・リアルタイム・サポートを実現するための変更を行います。変更内容には、カーネルのロック・プリミティブを完全にプリエンプト可能にするための再実装、カーネル内ミューテックスの優先度の継承の実装、そして完全にプリエンプト可能なカーネル・スレッドへの割り込みハンドラーの変換が含まれます。
まとめ
Linux はリアルタイム・アルゴリズムを実験して特性を解析するための理想的なプラットフォームになるだけでなく、今では既製の標準 2.6 カーネルにも Linux のリアルタイムが用意されています。この標準カーネルのソフト・リアルタイム・パフォーマンスをそのまま利用することも、あるいは多少手をかけて (カーネル・パッチを利用して)、ハード・リアルタイム・アプリケーションを構築することもできます。
この記事では、Linux カーネルにリアルタイム・コンピューティングをもたらすための手法をいくつか簡単に説明しました。初期の多くの試みでは、シン・カーネル方式によってリアルタイムのタスクを標準カーネルから隔離していました。その後、現在の仮想化ソリューションで用いられているハイパーバイザーに非常によく似たナノ・カーネル方式が登場し、そしてついに、Linux カーネル自体がソフト・リアルタイムとハード・リアルタイムの両方に対応する独自の手段を提供するようになっています。
この記事では Linux のリアルタイム方式を表面的にかじっただけですが、「参考文献」セクションに、さらに詳しい情報やその他にも役立つリアルタイム手法を調べるためのリンクを記載しています。
参考文献 学ぶために
製品や技術を入手するために
-
SEK for Linux を注文してください。この 2 枚組 DVD セットには、Linux 対応の DB2®、Lotus®、Rational®、Tivoli®、そして WebSphere® の最新 IBM トライアル・ソフトウェアが収録されています。
- developerWorks から直接ダウンロードできる IBM トライアル・ソフトウェアを使用して、Linux で次の開発プロジェクトを構築してください。
議論するために
著者について  | 
|  | M. Tim Jones は組み込みソフトウェアのエンジニアであり、『GNU/Linux Application Programming』や『AI Application Programming』、それに『BSD Sockets Programming from a Multilanguage Perspective』などの著者でもあります。技術的な経歴は静止軌道衛星用のカーネル開発から、組み込みシステム・アーキテクチャーやネットワーク・プロトコル開発まで、広範にわたっています。また、コロラド州ロングモン所在のEmulex Corp. の顧問エンジニアでもあります。 |
記事の評価
|