kubo39's blog

ただの雑記です。

mmap(2) はよく高速なメモリアクセスを実現するための手法と思われがちだけれど必ずしもそうではないよ、という話。

これはhenteko advent calender 4日目の記事です。

昨日は amothicさんのビール いず うまいでした。

hentekoさんですが、絶対に留年してると思ってたけど留年してなかったのであの時はブチ切れましたね。

尺が余ったのでてきとーにmmapの話します。

一般的にmmap(2)を使う場合はread(2)を呼ぶよりシステムコール呼び出しの回数が多くなります(stdioなどのバッファを使うわけではないので。まあ自前でバッファリングするんでしょうが)。システムコールはユーザ空間/カーネル空間を行き来するので実行コストが高くなることが知られています。 同様の問題はepoll<->pollなんかでも存在します。

mmap(2)を用いる利点を考える際、munmap(2)されるまではバッファの内容を書き込んだとしてもOSのページキャッシュにバッファのデータが残り続けるため、ランダムアクセスがread(2)に比べて高速になる点などが存在します。

またmmap(2)はシステムのメモリ管理に近いという特性上、ユーザ空間とカーネル空間でのメモリコピーが不要であるという点もパフォーマンスについて考えるのであれば留意すべきでしょう。

こういった点から、ランダムアクセスが多い場合やプロセス間でメモリを共有するのであればmmap(2)、シーケンシャルアクセスや即座に解放処理が走るような処理であればread(2)を用いたほうがよいと考えられます。

ちなみに、Linuxにはremap_file_pages(2)というシステムコールも存在しており、こちらは仮想メモリ領域のデータ構造を追加で作成する必要がないのでmmap(2)を連続で使うよりも高速な処理が期待できます。