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
Bash Loop Through Directory Including Hidden File
Any Good Guides on Using Ptrace_Sysemu
How to Let Users Run a Script with Root Permissions
How Can Beaglebone Black Be Used as Mass Storage Device
How Are Interrupts Handled on Smp
How to View Svn Diff in Vimdiff Style in Svn
Bash: Send Sigtstp Signal (Ctrl+Z)
How to Determine Thread Local Storage Model Used by a Library on Linux
How to Use Gpg Signing Key on a Remote Server
Sqlite Wal Performance Improvement
How to Remember Multiple Tabs' Session in Terminal? (Alike Ff Session Manager)
How to Get Maximum Tcp Receive/Send Window in MAC Os X