ディレクトリに1000000 4-20 kbのファイルがあります。そのディレクトリをコピーする必要があります。しかし、私は各ファイルをシークする必要があるようですので、これにはかなり時間がかかります。
これをスピードアップできる方法はありますか?
これらのファイルが占有するディスクブロックを取得できたら、それらを並べ替え、近いブロックをマージし(シーケンシャルリードがシークよりも高速であることが多い場合)、これらのブロックを読み取ってRAMにあると考えています。コピーする前にキャッシュ(32 GBのRAMを持っています)。
しかし、そのためには、ファイルがどのブロックにあるかを特定する方法が必要です。
磁気デバイス(つまりSSDではない)でEXT4を使用しています。
編集:
これは機能するはずですが、機能しません。
ls |
parallel -IOO --pipe "sudo parallel -j100 hdparm --fibmap {}'|tail -n +5'" |
sort -nk 2 |
perl -ane 'if($u+10000 < $F[1]) { print "$l ",($u-$l),"\n"; $l=$F[1] } $u=$F[2]' |
sudo parallel --colsep ' ' dd if=/dev/sda1 skip={1} bs=512 count={2} '| cat >/dev/null'
大きなファイルでテストする場合、ファイルはキャッシュされません。
Edit2:
ここにいくつかのベンチマークがあります。echo 3 >/proc/sys/vm/drop_caches
各実行の間にキャッシュがフラッシュされました()。で行われた測定iostats -dkx 5
。
rsync -Hav foo/ bar/: 1800 KB/s
cp -a foo/ bar/: 3600 KB/s
cat sort-by-inode | parallel -j1 -X cp foo/{} bar/: 5000 KB/s
cat sort-by-inode | shuf | parallel -j1 -X cp foo/{} bar/: 3000 KB/s
cat sort-by-inode | shuf | parallel -j10 -X cp foo/{} bar/: 7000 KB/s
cat sort-by-inode | parallel -j10 -X cp foo/{} bar/: 8000 KB/s
cat sort-by-inode | parallel -j100 -X cp foo/{} bar/: 9000 KB/s
cat sort-by-inode | parallel -j500 -X cp foo/{} bar/: 10000 KB/s
それから、私たちはそれから何を学ぶことができますか?
iノードによるソートは良い考えのようです。ただし、複数の並列化cp
によりパフォーマンスがさらに向上するようです。ソースfoo/
が磁気ディスクであることは強調する価値があるので、これはI / Oを単一のスピンドルに並列化してもI / Oを高速化しないという神話を攻撃します。
cp -r /mnt/dir1 /mnt/dirdest
またはのようなものcp /mnt/dir1/* /mnt/dirdest
ですか?