0

Why fallocate -c -l1GiB once cause the second loop of dd speed decrease from 1.0 GB to ~200 MB/s ?

xb@dnxb:~/Downloads/test$ fallocate -l 10.2GiB lala.mp4     
xb@dnxb:~/Downloads/test$ ls -larthiF --context --color
total 11G
41680908 drwxr-xr-x 121 xiaobai xiaobai ? 100K Dis   3 01:36 ../
53086804 drwxrwxr-x   2 xiaobai xiaobai ? 4.0K Dis   3 01:36 ./
53086805 -rw-rw-r--   1 xiaobai xiaobai ?  11G Dis   3 01:37 lala.mp4
xb@dnxb:~/Downloads/test$ f='lala.mp4'; n=0; while (( "$(stat --printf="%s" $f)" > 1073741824 )); do ((n++)); echo "[dd...$n]"; dd bs=1G skip=0 count=1 if=$f of="$f.$n"; fallocate -c -l1GiB $f; done; ((n++)); mv $f $f.$n; 
[dd...1]
1+0 records in
1+0 records out
1073741824 bytes (1.1 GB, 1.0 GiB) copied, 1.05744 s, 1.0 GB/s
[dd...2]
1+0 records in
1+0 records out
1073741824 bytes (1.1 GB, 1.0 GiB) copied, 3.24091 s, 331 MB/s
[dd...3]
1+0 records in
1+0 records out
1073741824 bytes (1.1 GB, 1.0 GiB) copied, 4.56858 s, 235 MB/s
[dd...4]
1+0 records in
1+0 records out
1073741824 bytes (1.1 GB, 1.0 GiB) copied, 4.02249 s, 267 MB/s
[dd...5]
1+0 records in
1+0 records out
1073741824 bytes (1.1 GB, 1.0 GiB) copied, 4.34307 s, 247 MB/s
[dd...6]
1+0 records in
1+0 records out
1073741824 bytes (1.1 GB, 1.0 GiB) copied, 4.27371 s, 251 MB/s
[dd...7]
1+0 records in
1+0 records out
1073741824 bytes (1.1 GB, 1.0 GiB) copied, 4.80721 s, 223 MB/s
[dd...8]
1+0 records in
1+0 records out
1073741824 bytes (1.1 GB, 1.0 GiB) copied, 4.17114 s, 257 MB/s
[dd...9]
1+0 records in
1+0 records out
1073741824 bytes (1.1 GB, 1.0 GiB) copied, 4.60627 s, 233 MB/s
[dd...10]
1+0 records in
1+0 records out
1073741824 bytes (1.1 GB, 1.0 GiB) copied, 4.13853 s, 259 MB/s
xb@dnxb:~/Downloads/test$ 
xb@dnxb:~/Downloads/test$ ls -larthiF --context --color
total 11G
41680908 drwxr-xr-x 121 xiaobai xiaobai ? 100K Dis   3 01:36 ../
53086806 -rw-rw-r--   1 xiaobai xiaobai ? 1.0G Dis   3 01:37 lala.mp4.1
53086807 -rw-rw-r--   1 xiaobai xiaobai ? 1.0G Dis   3 01:37 lala.mp4.2
53087049 -rw-rw-r--   1 xiaobai xiaobai ? 1.0G Dis   3 01:37 lala.mp4.3
53087910 -rw-rw-r--   1 xiaobai xiaobai ? 1.0G Dis   3 01:37 lala.mp4.4
53087911 -rw-rw-r--   1 xiaobai xiaobai ? 1.0G Dis   3 01:37 lala.mp4.5
53087913 -rw-rw-r--   1 xiaobai xiaobai ? 1.0G Dis   3 01:38 lala.mp4.6
53087914 -rw-rw-r--   1 xiaobai xiaobai ? 1.0G Dis   3 01:38 lala.mp4.7
53087962 -rw-rw-r--   1 xiaobai xiaobai ? 1.0G Dis   3 01:38 lala.mp4.8
53087963 -rw-rw-r--   1 xiaobai xiaobai ? 1.0G Dis   3 01:38 lala.mp4.9
53087964 -rw-rw-r--   1 xiaobai xiaobai ? 1.0G Dis   3 01:39 lala.mp4.10
53086805 -rw-rw-r--   1 xiaobai xiaobai ? 200M Dis   3 01:39 lala.mp4.11
53086804 drwxrwxr-x   2 xiaobai xiaobai ? 4.0K Dis   3 01:39 ./
xb@dnxb:~/Downloads/test$ 

[Update]

I noticed added sync before next dd will make it consistent again (sleep 120 also work, but not sleep 20), but the total time will slower since sync take more time than dd without sync:

xb@dnxb:~/Downloads/test$ f='lala.mp4'; n=0; while (( "$(stat --printf="%s" $f)" > 1073741824 )); do ((n++)); echo "[dd...$n]"; dd bs=1G skip=0 count=1 if=$f of="$f.$n"; fallocate -c -l1GiB $f; sync; done; ((n++)); mv $f $f.$n;
[dd...1]
1+0 records in
1+0 records out
1073741824 bytes (1.1 GB, 1.0 GiB) copied, 0.904357 s, 1.2 GB/s
[dd...2]
1+0 records in
1+0 records out
1073741824 bytes (1.1 GB, 1.0 GiB) copied, 0.902471 s, 1.2 GB/s
[dd...3]
1+0 records in
1+0 records out
1073741824 bytes (1.1 GB, 1.0 GiB) copied, 0.896056 s, 1.2 GB/s
...
林果皞
  • 4,946
  • 2
  • 29
  • 45

1 Answers1

2

Data is not directly written to the disk. The kernel keeps a cache. RAM is much faster than disk. The first dd benefit from this cache since it is not full. However, subsequent dd must wait for the cache to be flushed.

sync request all dirty pages to be flushed to disk. Otherwise they are flushed after several tens of seconds.

An ordinary disk is not capable of 1.2 GB/s, even an SSD, but is rightly around 300 MB/s .

user285259
  • 435
  • 2
  • 7