最速cp on UNIX Systems

ふとしたきっかけで、UNIX上における「最速cp」をやってみようと思い、いくつかの方法を実装してみた。

  • read -> write
  • read -> write with posix_fadvice
  • mmap -> mmap -> memcpy -> fsync
  • mmap -> mmap -> memcpy -> fsync with madvise
  • mmap -> mmap -> memcpy -> munmap
  • mmap -> mmap -> memcpy -> munmap with madvise
  • mmap -> write
  • mmap -> write with madvise

ソース

ソース

環境

Linux ubuntu 2.6.12-10-686 #1 Sat Mar 11 16:22:51 UTC 2006 i686 GNU/Linux
glibc 2.3.5-1ubuntu12

ベンチマーク

1Gのファイルを3回コピーし、その中で最速のものを取った。

./rw_cp ${SRC} ${DST}  0.07s user 8.42s system 5% cpu 2:28.12 total
./rw_fadv_cp ${SRC} ${DST}  0.05s user 6.54s system 4% cpu 2:37.58 total
./mm_sync_cp ${SRC} ${DST}  2.19s user 3.61s system 1% cpu 7:43.62 total
./mm_sync_madv_cp ${SRC} ${DST}  2.13s user 3.35s system 1% cpu 5:53.85 total
./mm_mun_cp ${SRC} ${DST}  2.23s user 3.09s system 1% cpu 6:56.09 total
./mm_mun_madv_cp ${SRC} ${DST}  2.14s user 2.69s system 1% cpu 5:59.98 total
./mw_cp ${SRC} ${DST}  0.00s user 5.25s system 3% cpu 2:51.23 total
./mw_madv_cp ${SRC} ${DST}  0.00s user 5.14s system 3% cpu 2:45.08 total

結果

  • read -> writeが一番早い
  • posix_fadviceはほとんど意味が無い
  • mmap with MAP_SHAREDした際にはmsyncで書き込むより、munmapで書き込んだ方が早い
  • madviseは効果が有る

感想

意外にもread -> writeが一番性能が出ているという結果になった。しかし納得が行かない。read -> writeだとkernel bufferからuser bufferへのコピーが発生するはずで、その分オーバーヘッドが発生する。mmap -> writeの場合はそういう事が起こらないはずなのだが、read -> writeよりも性能が出ない 。

何が起こっているのかよく分からない。カーネル読んでみてもちとよぅ分からず。もし知っておられる方がいらっしゃれば御教授お願いします...m(_ _)m他の環境でどうなるかも興味が有るので、もしよろしければベンチマークを取ってみて下さい。

理由が解明出来たらhtmlにして公開する予定。