Calculate Total Disk I/O by a Single Process

Calculate Total disk i/o by a single process

Feel free to play with this scribble (myio.sh):

#!/bin/bash 

TEMPFILE=$(tempfile) # create temp file for results

trap "rm $TEMPFILE; exit 1" SIGINT # cleanup after Ctrl+C

SECONDS=0 # reset timer

$@ & # execute command in background

IO=/proc/$!/io # io data of command
while [ -e $IO ]; do
cat $IO > "$TEMPFILE" # "copy" data
sed 's/.*/& Bytes/' "$TEMPFILE" | column -t
echo
sleep 1
done

S=$SECONDS # save timer

echo -e "\nPerformace after $S seconds:"
while IFS=" " read string value; do
echo $string $(($value/1024/1024/$S)) MByte/s
done < "$TEMPFILE" | column -t

rm "$TEMPFILE" # remove temp file

Syntax: ./myio.sh <your command>

Examples:

  • ./myio.sh dd if=/dev/zero of=/dev/null bs=1G count=4096
  • as root: ./myio.sh dd if=/dev/sda1 of=/dev/null bs=1M count=4096

Please change dd's of= in last example only if you know what you are doing.


With this simple script from me you can watch an already running process and its IO.

Syntax: pio.sh PID

#!/bin/bash

[ "$1" == "" ] && echo "Error: Missing PID" && exit 1
IO=/proc/$1/io # io data of PID
[ ! -e "$IO" ] && echo "Error: PID does not exist" && exit 2
I=3 # interval in seconds
SECONDS=0 # reset timer

echo "Watching command $(cat /proc/$1/comm) with PID $1"

IFS=" " read rchar wchar syscr syscw rbytes wbytes cwbytes < <(cut -d " " -f2 $IO | tr "\n" " ")

while [ -e $IO ]; do
IFS=" " read rchart wchart syscrt syscwt rbytest wbytest cwbytest < <(cut -d " " -f2 $IO | tr "\n" " ")

S=$SECONDS
[ $S -eq 0 ] && continue

cat << EOF
rchar: $((($rchart-$rchar)/1024/1024/$S)) MByte/s
wchar: $((($wchart-$wchar)/1024/1024/$S)) MByte/s
syscr: $((($syscrt-$syscr)/1024/1024/$S)) MByte/s
syscw: $((($syscwt-$syscw)/1024/1024/$S)) MByte/s
read_bytes: $((($rbytest-$rbytes)/1024/1024/$S)) MByte/s
write_bytes: $((($wbytest-$wbytest)/1024/1024/$S)) MByte/s
cancelled_write_bytes: $((($cwbytest-$cwbytes)/1024/1024/$S)) MByte/s
EOF
echo
sleep $I
done

Determine total amount of disk I/O read and write data (in bytes) for specified process in C#?

GetProcessIoCounters() is an concise alternative to Perf counters/WMI.

struct IO_COUNTERS {
public ulong ReadOperationCount;
public ulong WriteOperationCount;
public ulong OtherOperationCount;
public ulong ReadTransferCount;
public ulong WriteTransferCount;
public ulong OtherTransferCount;
}

...

[DllImport(@"kernel32.dll", SetLastError = true)]
static extern bool GetProcessIoCounters(IntPtr hProcess, out IO_COUNTERS counters);

...

if (GetProcessIoCounters(Process.GetCurrentProcess().Handle, out IO_COUNTERS counters)) {
Console.WriteLine(counters.ReadOperationCount);
...

Linux total disk I/O from already running process

You can read the /proc/<PID>/io file for specific process

 $ sudo cat /proc/1/io

rchar: 144440702940
wchar: 4615239440674
syscr: 156954128
syscw: 173077623
read_bytes: 113700176646
write_bytes: 100325525146
cancelled_write_bytes: 2596581376

C# Using GetProcessIoCounters to read total Disk IO per second (near realtime)

        IntPtr hProcess = GetCurrentProcess();
IO_COUNTERS lpIo1 = new IO_COUNTERS();
IO_COUNTERS lpIo2 = new IO_COUNTERS();
GetProcessIoCounters(hProcess, out lpIo1);

int Sec = 1;
Thread.Sleep(Sec * 1000);

GetProcessIoCounters(hProcess, out lpIo2);

ulong total1 = lpIo1.ReadOperationCount + lpIo1.WriteOperationCount + lpIo1.OtherOperationCount;
ulong total2 = lpIo2.ReadOperationCount + lpIo2.WriteOperationCount + lpIo2.OtherOperationCount;
ulong total = (total2 - total1) / Convert.ToUInt64(Sec);

Sec is the interval time between two GetProcessIoCounters. I use Thread.Sleep(Sec * 1000) to simulate the passage of Sec seconds.

Programmatically getting per-process disk io statistics on Windows?

You can call GetProcessIoCounters to get overall disk I/O data per process - you'll need to keep track of deltas and converting to time-based rate yourself.

This API will tell you total number of I/O operations as well as total bytes.

Determine total number of bytes read by a process

You can use GetProcessIOCounters function. This returns total read operations, write operations, other, read bytes, write bytes, and other bytes. The process still needs to be alive for this to work - holding a handle to the process should be sufficient. Alternatively, your process could log this info on exit.

If your goal is to reduce your disk I/O, I recommend you use the Windows Performance Toolkit. This will show you what files you are reading the most data from, which threads are reading the most data, and help give you a bit more of a system wide view as well, in case you are causing disk I/O elsewhere in the system.

how to find out what is causing I/O in my application?

Process Monitor may be your answer. Refer to the following StackOverflow question for more information.

How can I profile file I/O?

Building on that answer, you may be able to search your solution for the filename of any commonly read or written files found with Process Monitor.



Related Topics



Leave a reply



Submit