さまざまな(1.6GB)ブロックを読む同じファイルストアのtmpfs
最大速度は約20スレッドで2.5GB / sです。
ただし、同じチャンクが別のファイルに分割されると、tmpfs
22 GB / sになります。
このボトルネックの原因は何ですか?tmpfs
複数のファイルでできるだけ早く単一のファイルで作業する方法はありますか?
また現れる
書き込みは読み取りよりはるかに簡単ですが、問題と速度の違いは似ています。
$ cd /mnt/tmpfs
$ cores=$(seq 64)
$ # -u disables GNU Parallel's on-disk buffer
$ time parallel -n0 -u 'yes $(seq 1000) | head -c 1600M' ::: $cores > 100g
real 3m54.286s
user 1m10.592s
sys 246m42.804s
$ time parallel 'yes $(seq 1000) | head -c 1600M > {#}' ::: $cores
real 0m26.308s
user 1m21.283s
sys 24m45.152s
これには64個のコアと200GBのRAM(スワップなし)が必要ですtmpfs
が、より小さなハードウェアで効果を再現できます。
GNU Parallel がない場合は、次のように似た数字を取得できます。
time (
yes $(seq 1000) | head -c 1600M &
yes $(seq 1000) | head -c 1600M &
yes $(seq 1000) | head -c 1600M &
yes $(seq 1000) | head -c 1600M &
yes $(seq 1000) | head -c 1600M &
yes $(seq 1000) | head -c 1600M &
yes $(seq 1000) | head -c 1600M &
yes $(seq 1000) | head -c 1600M &
yes $(seq 1000) | head -c 1600M &
yes $(seq 1000) | head -c 1600M &
yes $(seq 1000) | head -c 1600M &
yes $(seq 1000) | head -c 1600M &
yes $(seq 1000) | head -c 1600M &
yes $(seq 1000) | head -c 1600M &
yes $(seq 1000) | head -c 1600M &
yes $(seq 1000) | head -c 1600M &
yes $(seq 1000) | head -c 1600M &
yes $(seq 1000) | head -c 1600M &
yes $(seq 1000) | head -c 1600M &
yes $(seq 1000) | head -c 1600M &
yes $(seq 1000) | head -c 1600M &
yes $(seq 1000) | head -c 1600M &
yes $(seq 1000) | head -c 1600M &
yes $(seq 1000) | head -c 1600M &
yes $(seq 1000) | head -c 1600M &
yes $(seq 1000) | head -c 1600M &
yes $(seq 1000) | head -c 1600M &
yes $(seq 1000) | head -c 1600M &
yes $(seq 1000) | head -c 1600M &
yes $(seq 1000) | head -c 1600M &
yes $(seq 1000) | head -c 1600M &
yes $(seq 1000) | head -c 1600M &
yes $(seq 1000) | head -c 1600M &
yes $(seq 1000) | head -c 1600M &
yes $(seq 1000) | head -c 1600M &
yes $(seq 1000) | head -c 1600M &
yes $(seq 1000) | head -c 1600M &
yes $(seq 1000) | head -c 1600M &
yes $(seq 1000) | head -c 1600M &
yes $(seq 1000) | head -c 1600M &
yes $(seq 1000) | head -c 1600M &
yes $(seq 1000) | head -c 1600M &
yes $(seq 1000) | head -c 1600M &
yes $(seq 1000) | head -c 1600M &
yes $(seq 1000) | head -c 1600M &
yes $(seq 1000) | head -c 1600M &
yes $(seq 1000) | head -c 1600M &
yes $(seq 1000) | head -c 1600M &
yes $(seq 1000) | head -c 1600M &
yes $(seq 1000) | head -c 1600M &
yes $(seq 1000) | head -c 1600M &
yes $(seq 1000) | head -c 1600M &
yes $(seq 1000) | head -c 1600M &
yes $(seq 1000) | head -c 1600M &
yes $(seq 1000) | head -c 1600M &
yes $(seq 1000) | head -c 1600M &
yes $(seq 1000) | head -c 1600M &
yes $(seq 1000) | head -c 1600M &
yes $(seq 1000) | head -c 1600M &
yes $(seq 1000) | head -c 1600M &
yes $(seq 1000) | head -c 1600M &
yes $(seq 1000) | head -c 1600M &
yes $(seq 1000) | head -c 1600M &
yes $(seq 1000) | head -c 1600M &
wait
) > 100g
time (
yes $(seq 1000) | head -c 1600M > 1 &
yes $(seq 1000) | head -c 1600M > 2 &
yes $(seq 1000) | head -c 1600M > 3 &
yes $(seq 1000) | head -c 1600M > 4 &
yes $(seq 1000) | head -c 1600M > 5 &
yes $(seq 1000) | head -c 1600M > 6 &
yes $(seq 1000) | head -c 1600M > 7 &
yes $(seq 1000) | head -c 1600M > 8 &
yes $(seq 1000) | head -c 1600M > 9 &
yes $(seq 1000) | head -c 1600M > 10 &
yes $(seq 1000) | head -c 1600M > 11 &
yes $(seq 1000) | head -c 1600M > 12 &
yes $(seq 1000) | head -c 1600M > 13 &
yes $(seq 1000) | head -c 1600M > 14 &
yes $(seq 1000) | head -c 1600M > 15 &
yes $(seq 1000) | head -c 1600M > 16 &
yes $(seq 1000) | head -c 1600M > 17 &
yes $(seq 1000) | head -c 1600M > 18 &
yes $(seq 1000) | head -c 1600M > 19 &
yes $(seq 1000) | head -c 1600M > 20 &
yes $(seq 1000) | head -c 1600M > 21 &
yes $(seq 1000) | head -c 1600M > 22 &
yes $(seq 1000) | head -c 1600M > 23 &
yes $(seq 1000) | head -c 1600M > 24 &
yes $(seq 1000) | head -c 1600M > 25 &
yes $(seq 1000) | head -c 1600M > 26 &
yes $(seq 1000) | head -c 1600M > 27 &
yes $(seq 1000) | head -c 1600M > 28 &
yes $(seq 1000) | head -c 1600M > 29 &
yes $(seq 1000) | head -c 1600M > 30 &
yes $(seq 1000) | head -c 1600M > 31 &
yes $(seq 1000) | head -c 1600M > 32 &
yes $(seq 1000) | head -c 1600M > 33 &
yes $(seq 1000) | head -c 1600M > 34 &
yes $(seq 1000) | head -c 1600M > 35 &
yes $(seq 1000) | head -c 1600M > 36 &
yes $(seq 1000) | head -c 1600M > 37 &
yes $(seq 1000) | head -c 1600M > 38 &
yes $(seq 1000) | head -c 1600M > 39 &
yes $(seq 1000) | head -c 1600M > 40 &
yes $(seq 1000) | head -c 1600M > 41 &
yes $(seq 1000) | head -c 1600M > 42 &
yes $(seq 1000) | head -c 1600M > 43 &
yes $(seq 1000) | head -c 1600M > 44 &
yes $(seq 1000) | head -c 1600M > 45 &
yes $(seq 1000) | head -c 1600M > 46 &
yes $(seq 1000) | head -c 1600M > 47 &
yes $(seq 1000) | head -c 1600M > 48 &
yes $(seq 1000) | head -c 1600M > 49 &
yes $(seq 1000) | head -c 1600M > 50 &
yes $(seq 1000) | head -c 1600M > 51 &
yes $(seq 1000) | head -c 1600M > 52 &
yes $(seq 1000) | head -c 1600M > 53 &
yes $(seq 1000) | head -c 1600M > 54 &
yes $(seq 1000) | head -c 1600M > 55 &
yes $(seq 1000) | head -c 1600M > 56 &
yes $(seq 1000) | head -c 1600M > 57 &
yes $(seq 1000) | head -c 1600M > 58 &
yes $(seq 1000) | head -c 1600M > 59 &
yes $(seq 1000) | head -c 1600M > 60 &
yes $(seq 1000) | head -c 1600M > 61 &
yes $(seq 1000) | head -c 1600M > 62 &
yes $(seq 1000) | head -c 1600M > 63 &
yes $(seq 1000) | head -c 1600M > 64 &
wait
)
tmpfs
Ubuntu 20.04のデフォルト値は次のとおりです。
$ uname -a
Linux r815 5.4.0-66-generic #74-Ubuntu SMP Wed Jan 27 22:54:38 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux
$ mount
tmpfs on /mnt/tmpfs type tmpfs (rw,noatime)
これは私たちに役立つかもしれませんが、同様の状況がHDDブロックデバイスにも当てはまるようです。
# Read the full disk into cache
sudo pv /dev/sde >/dev/null
# Read the full disk again from cache
time sudo cat /dev/sde >/dev/null
real 1m20.100s
user 0m0.739s
sys 1m19.351s
# Read the full disk again from cache 64 times in parallel
seq 64 | time sudo parallel -N0 'cat /dev/sde >/dev/null'
297.64user 39359.17system 12:44.60elapsed 5186%CPU (0avgtext+0avgdata 19752maxresident)k
0inputs+8outputs (0major+117384minor)pagefaults 0swaps
# Read the full disk again from cache as 64 parts in parallel
time sudo parallel -a /dev/sde --pipepart --block -1 -u 'cat >/dev/null'
real 1m5.796s
user 0m13.331s
sys 67m34.396s