단일 파일에 액세스하는 tmpfs는 여러 파일에 액세스하는 것보다 느립니다.

단일 파일에 액세스하는 tmpfs는 여러 파일에 액세스하는 것보다 느립니다.

다양한(1.6GB) 블록 읽기동일한파일 저장소의 tmpfs최대 속도는 약 20개의 스레드로 2.5GB/s입니다.

여기에 이미지 설명을 입력하세요.

그러나 동일한 청크가 다른 파일로 분할되면 tmpfs22GB/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
)

tmpfsUbuntu 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

관련 정보