20:45:46 # Life sendfile. spliceを直接利用していてあまり高速にならないなぁとおもってソースを眺めていたらsendfileがspliceで実装されていてカーネルの中で完結している感じで、 パイプをユーザ空間で用意したりしなくてよさそうなので使ってみた。 sendfileを使うとread/writeより高速にファイルをコピーできた。バッファのマネージメントもカーネルに任せれる。
copying 700MB file. read/write 1.11949 cached read/write 0.386885 splice 2.70374 cached splice 0.350746 sendfile 0.962656 cached sendfile 0.32921
16:36:18 # Life 日々のコーディング。 できるだけ自分の興味のあることを自分のためにコードする時間というのをとりたいなとおもってだれかのいってた毎日すこしづつやるハックを電車の中でやっているんだけどなかなか毎日はできないなぁ。
16:44:12 # Life Spliceとread/write. Linuxカーネルではspliceというシステムコールがあってそれだとファイルディスクリプタからファイルディスクリプタに直接コピー操作をさせることができる。read/writeでループするよりユーザ空間へのコピーがおこらないのでこちらのほうが効率が良さそうに思える。しかし手元でベンチマークとってみたところ、キャッシュにのっているときにはあまり差がないんだけど キャッシュにのっていないとき(/proc/sys/vm/drop_cachesした直後)に read/writeだと2秒でコピーが完了する680MBの ファイルがspliceだと3秒かかってた。 一回パイプを噛ませてるというのもあるかもだけど、うーん、なんでだろ。
ふと思いついてfallocateいれたら5倍位高速になった。しかしまだspliceのほうが遅い。一回Pipeを挟むからシステムコールの数が倍になるとかいうのは理由になるんだろうか。
17:30:45 # Life Ext4のExtent。ディスク上でどういう感じでファイルが配置されているのかなぁと興味が出たので調べてみた。 FS_IOC_FIEMAPというioctlがあって適当なファイルに対してリクエストするとstruct fiemapのデータ形式で返事がかえってくる。fiemap.fm_mapped_extents だけ返ってきて 最後のEXTENTだとFIEMAP_EXTENT_LASTフラグがfiemap_extent::fe_flagsに設定されている。 これはVFSレイヤーで実装されているのでファイルシステムどれでも同じようにかえってくることになっているっぽい。Documentation/filesystems/fiemap.txtにドキュメントが。 Extent毎にfe_logicalがファイルの論理的なオフセット、fe_lengthがそのExtentの長さ。
17:37:11 # Life ExtentレベルでのDedupe対応のファイルシステム。 同じデータの重複は排除して保持してほしいと思う今日このごろ。いいかげんpdumpfsとか rsync --link-destとかは古い気がする。 Extentを眺めているとFIEMAP_EXTENT_SHAREDというのがある。 ファイルシステムでioctl FIDEDUPERANGE、FICLONERANGE、FICLONEあたりを実装していると複数のファイルで共有しているExtentというのが存在しうるんだけどそれを表現しているっぽい。 どのファイルシステムが対応しているのかなぁと眺めたけど今のところ ocfs2 と btrfs だけ?
09:41:20 # Life read/write loop とsplice. ファイルのコピーをread/write システムコールを使ってやっているのがなんか無駄な気がしたのでふとspliceを使ってみた。 片側は必ずPipeじゃないといけないっぽいのでPipeを中間にもたせてループ。PIPEのバッファサイズは64kB単位。これはカーネル内部に決め打ちだった気もするけど最近はfcntl(F_SETPIPE_SZ)で設定できて1MBくらいまであげれるっぽい(/proc/sys/fs/pipe-max-size)。 mmapするのとどっちが原理的には速いのだろうか。ユーザ空間でアクセスする必要のないデータをユーザ空間で見れるようにコピーするのが遅いはずだし、mmapはやるたびにメモリマップをいじることになるのでそれをしなくてよいのは利点のはず。
17:49:11 # Life FUSEのメンテナが変わってるっぽい。libfuseはGithubに引っ越していてメンテナがNikolaus Rathに変わってる。一方カーネル側のメンテナはまだ変わっている気配がない。 Nikolausのメール
07:35:33 # Life cowfs. 何年も懸念だったFUSEでCowdancerを実装しなおしてみるというのをやってみた。 やってみたらいろんな人がやっていることに気づいたけどまぁいいか。 全部のレイヤーを提供できるのでCowdancerのようにinodeに依存する必要はなくて ファイルシステム構成をデータベースとかに保存することもできる。 かつデータを圧縮しておいて提供したりもできるのでFUSEでの実装は柔軟でいろいろな可能性があるなぁ。最初fusexmpをみたときはえらくAPIがでかいという印象だったけどいま振り返ってみると大体必要十分なAPIしかない気がする。 先月nftwのAPI調べたりsha1の速度調べたりしていたのはこのためだったので細かいこといろいろやってると実装するのに時間はかかる。
17:39:06 # Life FBADBEEF. 今日はなんかChromeがクラッシュしてた。 [ 7576.532634] chrome[1976]: segfault at fbadbeef ip 00007f08887bcca1 sp 00007ffcc90a37c0 error 6 in chrome[7f0885bf8000+5bb2000]
19:50:18 # Life FUSEでもっと遊んでみてる。 オーバレイファイルシステムを実装しているんだけどオーバレイされる下のファイルシステムはファイルディスクリプタさえあればopenatシステムコールなどで見れるっぽい挙動をしているのに気づいた。