This approach works by storing the shell process io counters from /proc/[pid]/io/
in an environment variable before running the process, and then subtracting them after the process ends.
For /proc/[pid]/io
counter definitions see:
In this example there are no read_bytes
or write_bytes
from/to storage:
> export proc_self_io="";while read line; do proc_self_io+="$line "; done < /proc/self/io
> head -c 100M < /dev/urandom > /dev/null
> perl -ane 'BEGIN{%prev=split / /,$ENV{proc_self_io}};printf( qq{%22s %i\n}, $F[0], $F[1]-$prev{$F[0]} ) ' /proc/$$/io
rchar: 104863647
wchar: 104858043
syscr: 12941
syscw: 25608
read_bytes: 0
write_bytes: 0
cancelled_write_bytes: 0
In this example there are write_bytes
to storage:
> export proc_self_io="";while read line; do proc_self_io+="$line "; done < /proc/self/io
> head -c 100M < /dev/urandom > /tmp/test.tmp
> perl -ane 'BEGIN{%prev=split / /,$ENV{proc_self_io}};printf( qq{%22s %i\n}, $F[0], $F[1]-$prev{$F[0]} ) ' /proc/$$/io
rchar: 104863684
wchar: 104857948
syscr: 12978
syscw: 25621
read_bytes: 0
write_bytes: 104857600
cancelled_write_bytes: 0
In this example there are no read_bytes
or write_bytes
from/to storage:
> export proc_self_io="";while read line; do proc_self_io+="$line "; done < /proc/self/io
> cat /tmp/test.tmp > /dev/null
> perl -ane 'BEGIN{%prev=split / /,$ENV{proc_self_io}};printf( qq{%22s %i\n}, $F[0], $F[1]-$prev{$F[0]} ) ' /proc/$$/io
rchar: 104863564
wchar: 104858183
syscr: 859
syscw: 836
read_bytes: 0
write_bytes: 0
cancelled_write_bytes: 0
There are 0 read_bytes
because /tmp/test.tmp
is all in memory(in core).
> fincore /tmp/test.tmp
RES PAGES SIZE FILE
100M 25600 100M /tmp/test.tmp
dd
can be used to perform direct IO from the input file, so now there are read_bytes
from storage:
> export proc_self_io="";while read line; do proc_self_io+="$line "; done < /proc/self/io
> dd if=/tmp/test.tmp of=/dev/null iflag=direct
204800+0 records in
204800+0 records out
104857600 bytes (105 MB, 100 MiB) copied, 5.77554 s, 18.2 MB/s
> perl -ane 'BEGIN{%prev=split / /,$ENV{proc_self_io}};printf( qq{%22s %i\n}, $F[0], $F[1]-$prev{$F[0]} ) ' /proc/$$/io
rchar: 104863573
wchar: 104858200
syscr: 204868
syscw: 204852
read_bytes: 104857600
write_bytes: 0
cancelled_write_bytes: 0
dd
can be used to perform direct IO from the input file and to the output file:
> export proc_self_io="";while read line; do proc_self_io+="$line "; done < /proc/self/io
> dd if=/tmp/test.tmp of=/tmp/test2.tmp iflag=direct oflag=direct
204800+0 records in
204800+0 records out
104857600 bytes (105 MB, 100 MiB) copied, 11.9083 s, 8.8 MB/s
> perl -ane 'BEGIN{%prev=split / /,$ENV{proc_self_io}};printf( qq{%22s %i\n}, $F[0], $F[1]-$prev{$F[0]} ) ' /proc/$$/io
rchar: 104863754
wchar: 104858310
syscr: 205049
syscw: 204863
read_bytes: 104857600
write_bytes: 104857600
cancelled_write_bytes: 0
> rm /tmp/test.tmp /tmp/test2.tmp
/proc/<PID>/io
and https://mcmap.net/q/396912/-what-do-the-counters-in-proc-pid-io-mean – Hays