システムコール

システムコール

執筆済 コンピュータOS

ユーザプログラムがカーネルに処理を依頼する仕組み。

ユーザモード
    │ syscall 命令
    ↓ ─────── 特権レベルの境界 ───────
カーネルモード
    │ 番号で処理を選び、引数を検証して実行
    ↓ sysret
ユーザモード

主なシステムコール#

分類
プロセス fork, execve, exit, wait
ファイル open, read, write, close
メモリ mmap, brk
通信 socket, send, recv
同期 futex

普段書く printfFile.read は、 最終的にこれらに帰着する。

なぜ関数呼び出しではないのか#

カーネルのコードをそのまま呼べてしまうと保護が成立しない。

専用の命令で、決められた入口からだけ入る。 カーネルは引数を検証してから処理する (ユーザが渡したポインタを信用してはいけない)。

コスト#

操作 おおよその時間
関数呼び出し 1 ナノ秒未満
システムコール 数百ナノ秒〜数マイクロ秒

特権レベルの切り替え、レジスタの保存、 キャッシュや TLB への影響がある。

Spectre / Meltdown の対策(KPTI)により、 このコストはさらに増えた。

減らす工夫#

工夫 内容
バッファリング printf は溜めてからまとめて write
mmap 読み書きをメモリアクセスに置き換える
io_uring リングバッファで一括投入・一括回収
vDSO gettimeofday などをユーザ空間で処理

「システムコールを 1 回減らす」ことが 実際に性能改善になる場面は多い。

参考文献#

ノート一覧を閉じる