Skip to content

Instantly share code, notes, and snippets.

@hackerb9
Created August 1, 2021 05:19
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save hackerb9/5cdaf4df38b8acf225e9056fa850a5f4 to your computer and use it in GitHub Desktop.
Save hackerb9/5cdaf4df38b8acf225e9056fa850a5f4 to your computer and use it in GitHub Desktop.
A quick hack, no-frills disk speed test. Works with any mountable filesystem (SSD/SATA/IDE/tmpfs...). Just specify the directory you'd like to write the test file to -- defaults to /tmp. Uses 'dd' for a quick test (default is 64MB) and then tries hdparm to run a three second test of direct I/O (no filesystem). It's just a shell script, so this s…
#!/bin/bash -e
# Bogus disk speed tester by b9 2016-2021
# Well, not exactly bogus, but overly simplistic.
TMPDIR=/tmp # where to write the file
COUNT=64 # number of blocks
BS=1 # blocksize (in *MEGA*bytes)
total=$((COUNT*BS))
[ "$1" ] && TMPDIR="$1" # Usage: bogodisk [dir [count]]
[ "$2" ] && COUNT="$2"
if [ $(id -u) != 0 ]; then
echo "Error: Results are too bogus if caches cannot be dropped." >&2
echo " Please try again as root." >&2
exit 1
fi
die() { echo -e "$@" >&2; exit 1; }
usage() { echo "Usage: bogodisk [tmpdir [#megabytes]]" >&2; exit 1; }
tmpfile=$(mktemp -p $TMPDIR bogodisk.XXXXX) || usage
trap 'rm $tmpfile 2>/dev/null' EXIT
set -o errexit # Exit immediately if a command fails.
set -o pipefail # Pipeline fails if any component fails.
export TIMEFORMAT=%3R # Runtime in seconds (3 places of precision)
read device fstype < <(df $TMPDIR --output=source,fstype | tail -1)
echo -e "Bogodisk 0.0:\tTesting $device ($fstype) with $total MB of data"
modelname=$(cat "/sys/class/block/${device#/dev/}/../device/model" 2>&-) \
&& echo -e "\t\t"${modelname#*:}
# TEST WRITE SPEED USING dd if=/dev/zero of=$tmpfile
echo -ne "\tDropping VM caches...\r"
echo 3 > /proc/sys/vm/drop_caches
# Preload executables
nice ionice dd if=/dev/zero of=/dev/null count=0 2>/dev/null; sync
echo -en "\tWriting $total MB ($COUNT blocks of size $BS MB)..."
output=$(time ( nice -15 ionice -c 1 \
dd if=/dev/zero of=$tmpfile bs=${BS}M count=$COUNT status=none && \
sync && sync ) 2>&1) \
|| die "\nError: Could not write $total MB to $tmpfile\n$output"
echo -e "\r\tWrote $total MB ($COUNT blocks of size $BS MB) in $output seconds"
writespeed=$(echo "scale=2; $total/$output" | bc)
# TEST READ SPEED USING dd if=$tmpfile of=/dev/null
echo -ne "\tDropping VM caches...\r"
echo 3 > /proc/sys/vm/drop_caches
# Preload executables
nice ionice dd if=/dev/zero of=/dev/null count=0 2>/dev/null; sync
echo -en "\tReading $total MB ($COUNT blocks of size $BS MB)..."
output=$(time ( nice -15 ionice -c 1 \
dd if=$tmpfile of=/dev/null bs=${BS}M count=$COUNT status=none; \
sync; sync ) 2>&1) \
|| die "\nError: Could not read from $tmpfile\n$output"
echo -e "\r\tRead $total MB ($COUNT blocks of size $BS MB) in $output seconds"
readspeed=$(echo "scale=2; $BS*$COUNT/$output" | bc)
printf "Write speed:%'12.2f MB/sec\n" $writespeed
printf "Read speed: %'12.2f MB/sec" $readspeed
echo -en "\t(...running hdparm...)\r"
printf "Read speed: %'12.2f MB/sec" $readspeed
if output=$(hdparm -t --direct $device 2>/dev/null | tail -1); then
maxread=$(echo ${output##*=})
echo -en "\t(theoretical max $maxread)\r"
else
echo -en "\t \r"
fi
printf "Read speed: %'12.2f MB/sec\n" $readspeed
@hackerb9
Copy link
Author

hackerb9 commented Aug 1, 2021

bogodisk

This gist is for you if you just want a quick estimate of your disk speed. No fancy programs to install, no baroque interfaces to learn. Runs easily on any typical GNU/Linux system: it's just a shell script.

Must be run as root to write to /proc/sys/vm/drop_caches

$ bogodisk 
Error: Results are too bogus if caches cannot be dropped.
       Please try again as root.

Example output

# bogodisk
Bogodisk 0.0:   Testing /dev/nvme0n1p2 (ext4) with 64 MB of data
                Samsung SSD 'Space-Train' 999 EVO DoublePlus 9TB
        Wrote 64 MB (64 blocks of size 1 MB) in 0.008 seconds
        Read  64 MB (64 blocks of size 1 MB) in 0.004 seconds
Write speed:    8,000.00 MB/sec
Read speed:    16,000.00 MB/sec (theoretical max 29513.11 MB/sec)

Testing a different disk

# mount /dev/sdb2 /mnt
# bogodisk /mnt
Bogodisk 0.0:   Testing /dev/nvme0n1p2 (ext4) with 64 MB of data
                Samsung SSD 970 EVO Plus 1TB
        Wrote 64 MB (64 blocks of size 1 MB) in 0.080 seconds
        Read  64 MB (64 blocks of size 1 MB) in 0.032 seconds
Write speed:      800.00 MB/sec
Read speed:     2,000.00 MB/sec (theoretical max 2955.40 MB/sec)
...
# bogodisk /dev/shm
Bogodisk 0.0:   Testing tmpfs (tmpfs) with 64 MB of data
        Wrote 64 MB (64 blocks of size 1 MB) in 0.034 seconds
        Read  64 MB (64 blocks of size 1 MB) in 0.014 seconds
Write speed:    1,882.35 MB/sec
Read speed:     4,571.42 MB/sec                           

Optionally you may increase the data size

Default is 64MB which happens to be a good compromise for current drives: it is small enough for old SATA drives to complete in a reasonable amount of time, yet is big enough that you can get a ballpark estimate of SSD speeds. Note that bash measures execution time in millisecond precision, at best, so you may need to increase the amount of data measured for fast drives or RAM filesystems like tmpfs. To do so, simply specify it (in MB) after the directory name. For example, this uses the default directory (/tmp) but writes 256MB.

# bogodisk /tmp 256

BUGS

  • Relies on features only found in the Linux kernel, such as echo 3 > /proc/sys/vm/drop_caches.
  • Why did I call this bogodisk when "disk" implies rotational media, a notion currently about as obsolete as a dodo trained to program in COBOL? Oh well, I also called it "bogo-" back in 2016 because I didn't think timing the speed of dd would work very well. However, the years have shown the worth of this useful little script.
  • Ideally, this should be even easier. There should be no way to specify the data size for a quality speed estimate because that should be discovered automatically. Likewise, instead of having people type in a directory name, they should be allowed to pick one of the mounted filesystems from a list.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment