カーネル機能がカーネル空間よりもユーザー空間でより速く再実装されるのはなぜですか?

カーネル機能がカーネル空間よりもユーザー空間でより速く再実装されるのはなぜですか?

本を読んでいますブログ投稿そして、次の文章に注意してください。

それから彼はとても素晴らしいことを言いました。 Seastar HTTPフレームワークでは、彼らは独自のTCPスタックを作成し、すべてを数倍速くしました。何? !

パフォーマンス上の理由から、カーネル機能がユーザー空間で再実装される理由を理解しようとしています。私は機能が(多くの)特権コマンドを実行するので、カーネルに正確に存在すると仮定します。さもなければ、機能は単にユーザ空間プログラムとして実装され得る。したがって、ユーザースペースのネットワークスタックなどのカーネル機能を再実装する場合(gVisorが実行する作業)ネットワークスタック例)結局、多くのシステムコールをカーネルで再度呼び出す必要があるので、多くのオーバーヘッドは発生しませんか?

従来、カーネルの一部であった機能をユーザー空間で再実装することで、多くのシステムコールを実行する必要はありませんか?では、たとえば、ネットワークスタックでどのように機能しますか?send()たとえば、頻繁に実行する必要があります。recv()

私は、ユーザー空間で機能を再実装すると、次の2つの潜在的な利点があることを理解しています。

  • カーネルに追加したものには依存しません(これは難しいプロセスのように見えます)。
  • ユーザースペースで再実装されたレガシーカーネル機能で脆弱性が発見された場合、これは「単なる」権限を持たないユーザースペースプロセスです。

しかし、私はこの問題のパフォーマンスにもっと興味があります。

ベストアンサー1

そのうちのいくつかは、システムコールの境界を超えるいくつかのトリップを避けるためのものです。

これは本当ですが、Linuxシステムコールインターフェイスは非常に一般的であり(つまり、さまざまな種類のアプリケーションとシステムを処理する必要があります)、非常に制限されています(システムコールパラメータは現在の要求に固有です)。カーネルは通常、コードが次に何をするのかほとんど分かりません。

findたとえば、見てみましょう。getdents、などのシステムコールに多くの時間を費やしますopendir。これを使用して多くの操作を実行できますが、find一般的なコマンドラインは次のとおりです。

find . -name 'report_201[89].txt' -print -quit

プログラムfindは多くのディレクトリを開き、多くのファイル名を読み込みます。このファイル名をユーザースペース機能に提供して、ファイル名があるかどうかを確認fnmatchします。report_2018.txtreport_2019.txt

しかし、これが.いくつかの最新のファイルシステムにあるとしましょう。これらのディレクトリは実際にはBツリーまたはハッシュテーブルです。カーネルが私たちが探しているファイル名を知っていれば、多くの処理時間を節約できます。

私たちがこれを見ているとしましょうgit status。システムコールを追跡すると、多くのlstatコールが発生します。しかし、実際に見つけようとしているのはユーザーがファイルシステムを変更しましたか?gitカーネルは基本的に答えを知っていますが、カーネルが知りたいことを知らせる方法はありません。したがって、すべてを自分で確認する必要があります(やや賢い方法で確認しますが)。

ここでの全体的なテーマは、カーネルAPIがアプリケーション固有の場合、状況がより効率的であることです。しかし、デザインの観点から見ると、本当に多様なアプリケーションがあるので言葉にならないことです。より広いカーネルインタフェースを維持することは、非常に線形的な複雑さを持つことができます。しかし、これがユーザースペースでより多くの問題を解決することによって(一部の問題の場合)効率を向上させることができる理由です。

おすすめ記事