システムコール
ユーザプログラムがカーネルに処理を依頼する仕組み。
ユーザモード
│ syscall 命令
↓ ─────── 特権レベルの境界 ───────
カーネルモード
│ 番号で処理を選び、引数を検証して実行
↓ sysret
ユーザモード主なシステムコール#
| 分類 | 例 |
|---|---|
| プロセス | fork, execve, exit, wait |
| ファイル | open, read, write, close |
| メモリ | mmap, brk |
| 通信 | socket, send, recv |
| 同期 | futex |
普段書く printf や File.read は、
最終的にこれらに帰着する。
なぜ関数呼び出しではないのか#
カーネルのコードをそのまま呼べてしまうと保護が成立しない。
専用の命令で、決められた入口からだけ入る。 カーネルは引数を検証してから処理する (ユーザが渡したポインタを信用してはいけない)。
コスト#
| 操作 | おおよその時間 |
|---|---|
| 関数呼び出し | 1 ナノ秒未満 |
| システムコール | 数百ナノ秒〜数マイクロ秒 |
特権レベルの切り替え、レジスタの保存、 キャッシュや TLB への影響がある。
Spectre / Meltdown の対策(KPTI)により、 このコストはさらに増えた。
減らす工夫#
| 工夫 | 内容 |
|---|---|
| バッファリング | printf は溜めてからまとめて write |
mmap |
読み書きをメモリアクセスに置き換える |
| io_uring | リングバッファで一括投入・一括回収 |
| vDSO | gettimeofday などをユーザ空間で処理 |
「システムコールを 1 回減らす」ことが 実際に性能改善になる場面は多い。
参考文献#
- Remzi H. Arpaci-Dusseau, Andrea C. Arpaci-Dusseau. Operating Systems: Three Easy Pieces. Arpaci-Dusseau Books, 2018.(全文公開) https://pages.cs.wisc.edu/~remzi/OSTEP/
- Randal E. Bryant, David R. O’Hallaron. Computer Systems: A Programmer’s Perspective, 3rd ed. Pearson, 2016. https://csapp.cs.cmu.edu/
- Linux kernel documentation. io_uring and I/O. https://docs.kernel.org/block/index.html
- Kernel Recipes / LWN. Ringing in a new asynchronous I/O API. LWN.net, 2019. https://lwn.net/Articles/776703/