Mach ( / m ɑː k / ) [ 1 ]は、カーネギーメロン大学でリチャード・ラシッドとアヴィ・テヴァニアンによって開発されたオペレーティングシステムカーネルで、主に分散コンピューティングと並列コンピューティングといったオペレーティングシステムの研究をサポートするために開発されました。Mach はマイクロカーネルの初期の例の一つとみなされることが多いですが、Mach のすべてのバージョンがマイクロカーネルというわけではありません。Mach の派生版は、 GNU Hurdのオペレーティングシステムカーネルや、macOS、iOS、iPadOS、tvOS、watchOSで使用されているAppleのXNUカーネルの基盤となっています。
カーネギーメロン大学でのプロジェクトは 1985 年から 1994 年まで続き、[ 2 ]真のマイクロカーネルである Mach 3.0 で終了しました。Mach は、BSD版Unixのカーネルの代替として開発され、それを中心に新しいオペレーティングシステムを設計する必要はありませんでした。Mach とその派生版は、XNU オペレーティングシステムカーネルを使用するすべてのものを含め、いくつかの商用オペレーティングシステムに存在し、XNU は Mach の以前の非マイクロカーネルバージョンを主要コンポーネントとして組み込んでいます。Mach仮想メモリ管理システムは、 CSRGの BSD 開発者によって 4.4BSD にも採用され、[ 3 ] FreeBSDなどの最新の BSD 派生 Unix システムにも登場しています。
Mach は、カーネギーメロン大学のAccent カーネルの論理的な後継者です。Mach の主任開発者である Richard Rashid は1991 年以来Microsoftに勤務しており、 Microsoft Research部門を設立しました。Mach の共同創設者である Avie Tevanian は、以前はNeXTのソフトウェア責任者であり、その後2006 年 3 月までApple Inc.の最高ソフトウェア技術責任者でした。 [ 4 ] [ 2 ]
開発者たちは雨のピッツバーグの泥水たまりを自転車で走り抜けて昼食に向かい、テヴァニアンは「muck」という言葉が彼らのマルチユーザー(またはマルチプロセッサユニバーサル)通信カーネルのバクロニムになるかもしれないと冗談を言った。イタリアのCMUエンジニア、ダリオ・ジューゼ[ 5 ]は後にプロジェクトリーダーのリック・ラシッドにプロジェクトの現在のタイトルについて尋ねたところ、「MUCK」という答えが返ってきたが、綴りは示されず、/ mʌk /と発音されただけだった。イタリア語のアルファベットに従って、彼は「Mach」と書いた。ラシッドはジューゼの綴り「Mach」を非常に気に入り、それが採用された。[ 6 ]: 103
オリジナルのUnixオペレーティングシステムにおける重要な概念の一つに、パイプという概念があります。パイプとは、データを非構造化バイトストリームとしてプログラム間で転送することを可能にする抽象化です。パイプを使用することで、ユーザーは複数のプログラムを連携させてタスクを完了させ、データを複数の小さなプログラムに連続して供給することができます。これは、当時の一般的なオペレーティングシステムとは対照的です。当時の一般的なオペレーティングシステムでは、タスク全体を処理できる単一の大きなプログラムが必要だったり、あるいは、リソースを大量に消費し、時間もかかるファイルを使ってデータを渡す必要がありました。
パイプは、基盤となる入出力システムの上に構築されました。このシステムは、ドライバがタスクの完了を待つ間、定期的に「ブロック」することを前提としたモデルに基づいています。たとえば、プリンタドライバがテキストの行をラインプリンタに送信した後、プリンタがその行の印刷を完了するまで何もする必要がない場合があります。この場合、ドライバはブロックされたことを通知し、オペレーティングシステムはプリンタがさらにデータを受け取る準備ができたことを示すまで、他のプログラムの実行を許可します。パイプシステムでは、限られたリソースはメモリであり、あるプログラムがパイプに割り当てられたメモリを使い切ると、当然ブロックされます。通常、これにより消費プログラムが実行され、パイプが再び空になります。ファイルの場合、次のプログラムが使用する前にファイル全体を読み書きする必要がありますが、パイプでは、プログラマの介入なしに、複数のプログラム間でデータを断片的に移動させることができました。
メモリバッファにパイプを実装すると、プログラム間でデータをコピーする必要が生じ、時間とリソースを大量に消費する処理となった。そのため、パイプの概念は、ほとんどのデバイスドライバのように、迅速な処理や低遅延が求められるタスクには不向きだった。オペレーティングシステムのカーネルとほとんどのコア機能は、代わりに単一の大きなプログラムとして記述された。コンピュータネットワークなどの新しい機能がオペレーティングシステムに追加されると、カーネルのサイズと複雑さも増大した。
Unixのパイプは、小さな協調プログラムから任意の複雑なソリューションを構築できる概念的なシステムを提供しました。これらの小さなプログラムは開発と保守が容易で、プログラミングとデバッグを簡素化する明確なインターフェースを備えていました。これらの特性は、サイズが小さくバグのないパフォーマンスが極めて重要なデバイスドライバにおいては、さらに価値がありました。カーネルも、同じように小さな協調プログラムに基づいてモデル化したいという強い要望がありました。
オペレーティングシステムの基盤としてパイプのようなシステムを採用した最初のシステムの1つが、ロチェスター大学で開発されたAlephカーネルでした。これは、本質的には共有メモリの実装であるポートの概念を導入しました。Alephでは、カーネルはメモリやポートを含むハードウェアへのアクセスを提供するだけの役割に縮小され、デバイスドライバからユーザープログラムまで、すべての動作はポートシステムを使用する従来のプログラムによって実装されました。この概念によりカーネルのサイズが大幅に縮小され、ユーザーは実行時にドライバをロードして接続するだけで、さまざまなドライバを簡単に試すことができました。これにより、新しいオペレーティングシステムコードを開発する際に、マシンを再起動する必要があった問題が大幅に軽減されました。小さなカーネルと外部ドライバという全体的な概念は、マイクロカーネルとして知られるようになりました。
Alephはデータゼネラル社のEclipseミニコンピュータ上で実装され、それらのコンピュータに密接に依存していた。このマシンは、プログラム間でメモリをコピーする必要があり、パフォーマンスに大きなオーバーヘッドが発生するため、決して理想的なものではなかった。また、価格も非常に高かった。それでも、Alephは基本システムの健全性を証明し、初期のイーサネットインターフェースを介してメモリをコピーすることで、コンピュータクラスタリングの実証に成功した。
この頃、32ビットのアドレス空間と(当初はオプションだった)メモリ管理ユニット(MMU)をサポートする新世代の中央処理装置(CPU)が市場に登場しました。MMUは、様々なプログラムがどのメモリページを使用しているかを追跡することで、仮想メモリシステムを実装するために必要な命令を処理しました。これにより、仮想メモリシステムが提供するコピーオンライト(COW)メカニズムを利用した、ポートの概念に対する新たな解決策が生まれました。プログラム間でデータをコピーする代わりに、MMUに同じメモリへのアクセスを提供するよう指示するだけで済むようになりました。このシステムは、プロセス間通信(IPC)システムを劇的に高いパフォーマンスで実現するものでした。
このコンセプトはカーネギーメロン大学で採用され、同大学はAlephをPERQワークステーション向けに改良し、コピーオンライト方式で実装した。移植は成功したが、結果として生まれたAccentカーネルは既存のソフトウェアを実行できなかったため、実用性は限られていた。さらに、AccentはAlephがEclipseに依存していたのと同様に、PERQに密接に依存していた。
これらの実験的なカーネルと Mach の大きな違いは、既存の4.2BSDカーネルのバージョンを Accent メッセージパッシングの概念に基づいて再実装するという決定でした。このようなカーネルは既存のBSDソフトウェアとバイナリ互換性があり、システムはすぐに日常的に使用できると同時に、有用な実験プラットフォームにもなります。さらに、新しいカーネルは最初から複数のプロセッサ アーキテクチャをサポートするように設計され、異種クラスタの構築も可能になります。システムをできるだけ早く立ち上げるために、システムは既存の BSD コードから始めて、プロセス間通信( IPC) ベースのプログラムとして徐々に再実装することで実装されます。したがって、Mach は既存の UNIX システムと同様のモノリシック システムとして始まり、時間の経過とともにマイクロカーネルの概念へと進んでいきます。[ 4 ]
Mach は、明確に定義された UNIX ベースの移植性の高い Accent を作成するための取り組みとして始まりました。その結果、汎用的な概念の短いリストができました。[ 7 ] [ 8 ]
MachはAccentのIPC(プロセス間通信)の概念を基に開発されましたが、UNIXに非常に近いシステムとなり、UNIXプログラムをほとんど、あるいは全く変更せずに実行できるようにしました。そのため、Machは双方向IPCの各エンドポイントを表すポートを導入しました。ポートにはUNIXのファイルと同様のパーミッションの概念があり、UNIXに非常に近い保護モデルを適用することが可能でした。さらに、Machは、通常はオペレーティングシステムのみに与えられる権限を任意のプログラムが処理できるようにすることで、ユーザー空間プログラムがハードウェアの制御などの処理を行えるようにしました。
Machでは、UNIXと同様に、オペレーティングシステムは再び主にユーティリティの集合体となる。UNIXと同様に、Machはハードウェアを扱うためのドライバの概念を維持している。そのため、現在のハードウェア用のすべてのドライバはマイクロカーネルに含める必要がある。ハードウェア抽象化レイヤーやエクソカーネルに基づく他のアーキテクチャでは、ドライバをマイクロカーネルから分離することができる。
UNIXとの主な違いは、ユーティリティがファイルを処理する代わりに、あらゆる「タスク」を処理できる点です。オペレーティングシステムのコードの多くがカーネルからユーザー空間に移動され、カーネルが大幅に小さくなり、マイクロカーネルという用語が生まれました。従来のシステムとは異なり、Machではプロセス、つまり「タスク」は複数のスレッドで構成できます。これは現代のシステムでは一般的ですが、Machはこのようにタスクとスレッドを定義した最初のシステムでした。カーネルの役割は、基本的にオペレーティングシステムであることから、「ユーティリティ」を実行し、ハードウェアへのアクセスを提供するものへと縮小されました。
Machと従来のカーネルの最も根本的な違いは、ポートの存在とIPCの使用にあると言えるでしょう。UNIXでは、カーネルの呼び出しはシステムコールまたはトラップと呼ばれる操作で構成されます。プログラムはライブラリを使用してメモリ内の既知の場所にデータを配置し、その後、フォルト(一種のエラー)を発生させます。システムが最初に起動されると、カーネルはすべてのフォルトの「ハンドラ」として設定されます。したがって、プログラムがフォルトを発生させると、カーネルが引き継ぎ、渡された情報を調べ、命令を実行します。
Machでは、この役割にIPCシステムが用いられていました。システム機能を呼び出すには、プログラムはカーネルにポートへのアクセスを要求し、その後IPCシステムを使ってそのポートにメッセージを送信します。メッセージの送信にはシステムコールが必要ですが、他のシステムでシステム機能を要求する場合と同様に、Machではメッセージの送信がカーネルのほぼ全てであり、実際の要求処理は別のプログラムが行います。
IPCメカニズムによるメッセージパッシングによって、スレッドと並行処理のサポートが向上しました。タスクが複数のコードスレッドで構成されるようになり、Machはメッセージ処理中にこれらのスレッドをフリーズおよびフリーズ解除できるようになったためです。これにより、ほとんどのMachメッセージのように共有メモリを直接使用するか、必要に応じてメッセージを別のプロセッサにコピーするコードを追加することで、システムを複数のプロセッサに分散させることができます。従来のカーネルでは、これを実装するのは困難です。システムは、異なるプログラムが異なるプロセッサから同じメモリ領域に書き込もうとしないようにする必要があります。しかし、Machポートを使用すると、これが明確に定義され、簡単に実装できるため、Machポートはこのシステムで第一級の要素となりました。
IPCシステムは当初パフォーマンスの問題を抱えていたため、パフォーマンスを向上させるためのいくつかの戦略が開発されました。前身のAccentと同様に、Machは単一の共有メモリ機構を使用して、メッセージをあるプログラムから別のプログラムへ物理的に渡していました。メッセージを物理的にコピーするのは遅すぎるため、Machはマシンのメモリ管理ユニット(MMU)を利用して、あるプログラムから別のプログラムへデータを高速にマッピングします。データが書き込まれる場合にのみ、物理的にコピーする必要があり、このプロセスは「コピーオンライト」と呼ばれます。
システムを構成する多数のプログラムのいずれかが不正なデータによってクラッシュするのを防ぐため、メッセージの妥当性はカーネルによってもチェックされました。ポートは意図的にUNIXファイルシステムの概念に基づいて設計されています。これにより、ユーザーは既存のファイルシステムナビゲーションの概念を使用してポートを検索できるだけでなく、ファイルシステムで行うのと同様に権限やアクセス許可を割り当てることができます。
このようなシステムの下での開発は容易になるだろう。作業対象のコードは、既存のツールを使って構築できる従来のプログラムとして存在するだけでなく、同じツールを使って起動、デバッグ、終了もできる。単一カーネルの場合、新しいコードにバグがあるとマシン全体がダウンし、再起動が必要になるが、Machではプログラムを再起動するだけで済む。さらに、ユーザーは必要な機能をシステムに追加したり除外したりしてカスタマイズできる。オペレーティングシステムは単なるプログラムの集合体であるため、他のプログラムと同様に、実行したり終了させたりするだけで、必要な部分を追加したり削除したりできる。
最後に、Machにおいては、これらの機能はすべて、極めてプラットフォームに依存しないように意図的に設計されました。Machに関するある文献を引用すると、次のようになります。
しかし、いくつかの欠点もあります。比較的ありふれた欠点としては、ポートを見つける方法が明確でないことが挙げられます。UNIXでは、プログラマーたちがファイルシステム内のさまざまな用途に対応する「よく知られた」場所をいくつか合意することで、この問題は徐々に解決されました。このアプローチはMachのポートにも有効でしたが、Machではオペレーティングシステムがはるかに流動的で、ポートが常に出現したり消滅したりすると想定されていました。ポートとそのポートが表すサービスを見つけるための何らかのメカニズムがなければ、この柔軟性の多くが失われてしまいます。
Machは当初、既存の4.2BSDカーネルに直接書き込まれた追加コードとしてホストされていたため、チームはシステムが完成するずっと前から作業を進めることができた。作業は既に機能していたAccent IPC/ポートシステムから始まり、タスク、スレッド、仮想メモリといったOSの他の主要部分へと進んだ。各部分が完成するにつれて、BSDシステムのさまざまな部分がMachを呼び出すように書き換えられ、この過程で4.3BSDへの変更も行われた。
1986年までに、システムはDEC VAX上で単独で動作できるまでに完成した。実用的な価値はほとんどなかったものの、マイクロカーネルを作成するという目標は達成された。その後すぐに、IBM RT PC版とSun Microsystems 68030ベースのワークステーション版がリリースされ、システムの移植性が証明された。1987年には、Encore MultimaxとSequent Balanceマシンがリストに追加され、Machがマルチプロセッサシステム上で動作する能力がテストされた。同年、リリース1が公開され、翌年にはリリース2がリリースされた。
この間ずっと、「真の」マイクロカーネルという約束はまだ果たされていませんでした。初期のMachバージョンは、カーネルに4.3BSDの大部分(POEサーバーと呼ばれるシステム)を含んでおり、結果として、ベースとなったUNIXよりも大きなカーネルになっていました。しかし、そのアイデアは、UNIXレイヤーをカーネルからユーザー空間に移し、そこでより簡単に作業したり、完全に置き換えたりできるようにすることでした。残念ながら、パフォーマンスが大きな問題であることが判明し、この問題を解決するために多くのアーキテクチャ変更が行われました。扱いにくいUNIXライセンスの問題も研究者を悩ませていたため、ライセンス不要のUNIXライクなシステム環境を提供するこの初期の取り組みは、Machのさらなる開発においても引き続き利用されました。
その結果生まれたMach 3は1990年にリリースされ、大きな注目を集めた。小規模なチームがMachを開発し、旧式のカーネルでは深刻な問題となっていた複雑なマルチプロセッサシステムを含む、数多くのプラットフォームに移植したのだ。これにより、多くの企業がハードウェアプラットフォームの変更を検討していた商用市場で大きな関心が寄せられた。既存のシステムをMach上で動作するように移植できれば、基盤となるプラットフォームの変更も容易になると考えられたからである。
Mach は、Open Software Foundation (OSF) がOSF/1の将来のバージョンをMach 2.5 でホストし、Mach 3 も調査していると発表したことで、認知度が大幅に向上しました。Mach 2.5 は、 NeXTSTEPシステムや多数の商用マルチプロセッサベンダーにも採用されました。Mach 3 は、IBMのWorkplace OSやAppleによるクラシック Mac OSのクロスプラットフォーム版の構築など、他のオペレーティングシステムのパーツをマイクロカーネルに移植する取り組みにつながりました。[ 10 ]研究者らは、 Mach 2.5 でクラシック Mac OS とMultiFinderを実行する以前の作業に続き、Mach 3.0 環境で DOS アプリケーションを実行するサポートを実証しました。 [ 11 ] Digital Equipment Corporationの研究プロジェクトでは、Mach 3 カーネル上でOpenVMS をホストする実現可能性を調査し、VMS の機能のサブセットを使用した概念実証を作成しました。[ 12 ]
Machは元々、従来のモノリシックなUNIXの代替として開発されたため、UNIXに似た多くのアイデアが盛り込まれていました。例えば、MachはUNIXのファイルシステムと同様のパーミッションとセキュリティシステムを提供していました。カーネルは他のOSサーバーやソフトウェアよりも特権(カーネル空間で実行)を持っていたため、誤動作したり悪意のあるプログラムがシステムに損害を与えるコマンドをカーネルに送信する可能性がありました。そのため、カーネルはすべてのメッセージの正当性をチェックしていました。さらに、オペレーティングシステムの機能の大部分はユーザー空間プログラムに配置される予定だったため、カーネルがこれらのプログラムに追加の権限(例えば、ハードウェアへの直接アクセス権限)を付与する方法が必要でした。
Machのより高度な機能のいくつかも、この同じIPCメカニズムに基づいていた。例えば、Machはマルチプロセッサマシンを容易にサポートできた。従来のカーネルでは、異なるプロセッサで実行されているプログラムが同時にカーネルを呼び出す可能性があるため、再入可能または割り込み可能にするために大規模な作業が必要となる。Machでは、オペレーティングシステムの各部分はサーバーに分離されており、他のプログラムと同様に、どのプロセッサでも実行できる。理論的にはMachカーネルも再入可能である必要があるが、実際には応答時間が非常に速いため、順番にリクエストを待機して処理するだけで済むため、これは問題にならない。Machには、プログラム間だけでなく、ネットワーク経由でもメッセージを転送できるサーバーも含まれていた。ネットワークは1980年代後半から1990年代初頭にかけて集中的に開発された分野である。
残念ながら、ほぼすべてのタスクで IPC を使用すると、パフォーマンスに深刻な影響が出ることが判明しました。1997 年のハードウェアでのベンチマークでは、Mach 3.0 ベースのUNIXシングルサーバー実装はネイティブ UNIX より約 50% 遅いことが示されました。[ 13 ] [ 14 ]
パフォーマンスの問題の正確な性質を調査したところ、興味深い事実がいくつか明らかになった。 1 つは、IPC が問題ではなかったということである。IPC をサポートするために必要なメモリ マッピングに関連するオーバーヘッドはあったが、これは呼び出しにわずかな時間を追加するだけであった。残りの時間の 80% は、カーネルがメッセージに対して実行している追加のタスクによるものであった。その中でも主要なものは、ポート権限のチェックとメッセージの有効性であった。486 DX-50 でのベンチマークでは、標準的な UNIX システム コールの完了に平均 21 μsかかったが、Mach IPC を使用した同等の操作では平均 114 μs かかった。このうちハードウェア関連の時間は 18 μs のみで、残りは Mach カーネルがメッセージに対してさまざまなルーチンを実行する時間であった。[ 15 ]何もしないシステム コールの場合、BSD での完全な往復には約 40 μs かかるが、ユーザー スペース Mach システムでは 500 μs 弱かかる。
Mach が 2.x バージョンで本格的に使用され始めた当初は、パフォーマンスは従来のモノリシックなオペレーティングシステムよりも遅く、おそらく 25% ほど遅かった。[ 1 ]しかし、このコストは、システムがマルチプロセッサのサポートと容易な移植性も提供していたため、特に心配する必要はないと考えられていた。多くの人が、これは想定内の許容できるコストだと感じていた。Mach 3 がオペレーティングシステムの大部分をユーザー空間に移動しようとしたとき、オーバーヘッドはさらに高くなった。MIPS R3000上での Mach とUltrix のベンチマークでは、一部のワークロードでパフォーマンスが 67% も低下したことが示された。[ 16 ]
例えば、システム時刻を取得するには、システムクロックを管理するユーザー空間サーバーへのIPC呼び出しが必要です。呼び出し元はまずカーネルにトラップし、コンテキストスイッチとメモリマッピングが発生します。次にカーネルは、呼び出し元が必要なアクセス権限を持っているか、メッセージが有効かを確認します。有効であれば、ユーザー空間サーバーへの呼び出しを完了するために、さらにコンテキストスイッチとメモリマッピングが行われます。結果を返すにはこのプロセスを繰り返す必要があり、合計で4回のコンテキストスイッチとメモリマッピング、さらに2回のメッセージ検証が発生します。このようなオーバーヘッドは、多くのサーバーを経由するコードパスが多い複雑なサービスでは急速に増大します。
パフォーマンスの問題の原因はこれだけではありませんでした。もう一つは、物理メモリが不足してページングが必要になったときに、メモリを適切に処理しようとする際の問題でした。従来のモノリシックなオペレーティングシステムでは、カーネルのどの部分が他のどの部分を呼び出すかを直接把握していたため、ページャーを微調整して、使用しようとしているコードをページアウトしないようにすることができました。Mach では、カーネルがオペレーティングシステムの構成要素を実際には把握していなかったため、これは不可能でした。代わりに、単一の汎用的なソリューションを使用する必要があり、これがパフォーマンスの問題をさらに悪化させました。Mach 3 は、より優れた特化のためにユーザー空間ページャーに依存するシンプルなページャーを提供することで、この問題に対処しようとしました。しかし、これはほとんど効果がありませんでした。実際には、その利点は、呼び出しに必要なコストのかかる IPC によって相殺されてしまいました。
その他のパフォーマンス問題は、Machのマルチプロセッサシステムへの対応に関連していた。1980年代半ばから1990年代初頭にかけて、汎用CPUの性能は年間約60%の割合で向上したが、メモリアクセスの速度は年間わずか7%しか向上しなかった。つまり、この期間にメモリへのアクセスコストが飛躍的に増加し、Machはプログラム間でメモリをマッピングする方式に基づいていたため、「キャッシュミス」が発生するとIPC呼び出しが遅くなった。
IPCオーバーヘッドはMach 3システムにとって大きな課題です。マルチサーバーオペレーティングシステムのコンセプトは依然として有望ですが、さらなる研究が必要です。開発者は、サーバー間呼び出しを行わないモジュールにコードを分離するよう注意する必要があります。例えば、ネットワークコードの大部分を単一のサーバーに配置することで、通常のネットワークタスクにおけるIPCを最小限に抑えることができます。
ほとんどの開発者は、代わりに、オペレーティングシステムの機能を提供する単一の大きなサーバーという元の POE コンセプトに固執しました。[ 17 ]開発を容易にするために、オペレーティングシステムサーバーがユーザー空間またはカーネル空間のどちらでも実行できるようにしました。これにより、ユーザー空間で開発して元の Mach のアイデアのすべての利点を享受し、その後、デバッグされたサーバーをカーネル空間に移動してパフォーマンスを向上させることができました。その後、この方法を使用して構築されたオペレーティングシステムがいくつかあり、これはコロケーションとして知られており、その中にはLites、MkLinux、OSF/1、NeXTSTEP/OPENSTEP/macOS などがあります。Chorusマイクロカーネルはこれを基本システムの機能とし、組み込みのメカニズムを使用してサーバーをカーネル空間に昇格できるようにしました。
Mach 4 は、より抜本的なアップグレードによってこれらの問題に対処しようと試みました。特に、プログラムコードは通常書き込み可能ではないため、コピーオンライトによる潜在的なヒットはまれであることが判明しました。そのため、プログラム間で IPC 用のメモリをマッピングするのではなく、使用されているプログラムコードをプログラムのローカル空間に移行することが理にかなっていました。これにより「シャトル」の概念が生まれ、パフォーマンスが向上したように見えましたが、開発者はシステムを半ば使用可能な状態で先に進めました。Mach 4 では、組み込みのコロケーション プリミティブも導入され、カーネルの一部となりました。
1990 年代半ばまでに、マイクロカーネル システムの開発はほぼ停滞していたが、市場では一般的に、1990 年代までにすべての最新のオペレーティングシステムがマイクロカーネル ベースになると考えられていた。 Mach カーネルの主な残存する広く使用されている用途は、Apple の macOS とその兄弟である iOS であり、これらは OSF/1 [ 10 ]でも使用されている「 XNU」[ 18 ]と呼ばれる大幅に修正されたハイブリッドOpen Software Foundation Mach Kernel (OSFMK 7.3)上で動作している。 XNU では、ファイルシステム、ネットワーク スタック、プロセスおよびメモリ管理機能がカーネルに実装されており、ファイルシステム、ネットワーク、および一部のプロセスおよびメモリ管理機能は、メッセージ パッシングではなく通常のシステム コールを介してユーザー モードから呼び出される。 [ 19 ] [ 20 ] XNU の Mach メッセージは、ユーザー モード プロセス間の通信、およびユーザー モード コードからカーネルへの要求、カーネルからユーザー モード サーバーへの要求に使用される。
さらなる分析により、IPC パフォーマンスの問題は見た目ほど明白ではないことが明らかになった。BSD [ 3 ]ではシステムコールの片側が 20μs かかり、同じシステムで実行されている Mach [ 2 ]では 114μs かかったことを思い出してほしい。114のうち 11 はコンテキストスイッチによるもので、BSD と同じである[ 14 ] 。さらに 18 は、MMU がユーザー空間とカーネル空間の間でメッセージをマッピングするために使用された [ 3 ]。これらを合計するとわずか 29μs で、従来のシステムコールよりは長いが、それほど大きな差ではない。
残りの問題の大部分は、カーネルがポートアクセス権限のメッセージチェックなどのタスクを実行することによるものでした。[ 6 ]これは重要なセキュリティ上の懸念事項のように思えますが、実際には、UNIX ライクなシステムでのみ意味があります。たとえば、携帯電話やロボットを実行するシングルユーザーオペレーティングシステムでは、これらの機能は必要ないかもしれません。そして、まさにこのようなシステムで、Mach の選択型オペレーティングシステムが最も価値を発揮します。同様に、オペレーティングシステムによってメモリが移動された場合にも、Mach は問題を引き起こしました。これも、システムが複数のアドレス空間を持っている場合にのみ意味のあるタスクです。DOSと初期のMac OS は、すべてのプログラムで共有される単一の大きなアドレス空間を持っているため、これらのシステムではマッピングによるメリットはありませんでした。
これらの認識により、第2世代のマイクロカーネルが開発され、システムの複雑さがさらに軽減され、ほぼすべての機能がユーザー空間に配置されました。たとえば、L4カーネル(バージョン2)にはシステムコールが7つしか含まれておらず、メモリ使用量は12kですが[ 3 ] 、 Mach 3には約140の関数が含まれており、メモリ使用量は約330kです[ 3 ] 。486DX -50上のL4でのIPC呼び出しはわずか5μsで完了し[ 20 ]、同じシステムのUNIXシステムコールよりも高速で、Machよりも20倍以上高速です。もちろん、これはL4がパーミッションやセキュリティを処理していないという事実を無視していますが、これをユーザー空間プログラムに任せることで、必要なだけオーバーヘッドを選択できるようになります。
L4 の潜在的なパフォーマンス向上は、ユーザー空間アプリケーションが、以前はカーネルによってサポートされていた多くの機能を提供する必要があるという事実によって抑制されます。エンドツーエンドのパフォーマンスをテストするために、共存モードの MkLinux をユーザー空間で実行されている L4 ポートと比較しました。L4 は約 5%~10% のオーバーヘッドを追加しましたが、Mach の 29% と比較すると[ 14 ]それほどではありません。
以下は、Machから派生したオペレーティングシステムカーネルと、Machから派生したカーネルを持つオペレーティングシステムの一覧です。