mreschke

mreschke / speedtest-hd.py

Last active 1 month ago

Like 0

Hard drive speed test using fio or dd

mreschke revised this gist 2 months ago · c00ead1

1 file changed, 1 insertion, 2 deletions

speedtest-hd.py
@@ -2,5 +2,4 @@
2 2 # See https://git.mreschke.net/mreschke/speedtest-hd
3 3
4 4 # Quick Install
5 -
6 - wget https://git.mreschke.net/mreschke/speedtest-hd/raw/branch/master/speedtest-hd.py
5 + wget https://git.mreschke.net/mreschke/speedtest-hd/raw/branch/master/speedtest-hd.py && chmod a+x speedtest-hd.py

mreschke revised this gist 2 months ago · 7513982

1 file changed, 4 insertions, 729 deletions

speedtest-hd.py

Diff is too large to be shown

mreschke revised this gist 2 months ago · ff28788

2 files changed, 731 insertions, 366 deletions

speedtest-hd.py (file created)

Diff is too large to be shown

speedtest-hd.sh (file deleted)

Diff is too large to be shown

mreschke revised this gist 2 months ago · 3f5fba9

1 file changed, 47 insertions, 19 deletions

speedtest-hd.sh
@@ -9,7 +9,15 @@
9 9
10 10 # CLI Parameters
11 11 path="$1"
12 - option="$2"
12 + option=""
13 + simple=false
14 + for arg in "${@:2}"; do
15 + case "$arg" in
16 + --simple) simple=true ;;
17 + --dd) option="--dd" ;;
18 + --fio) option="--fio" ;;
19 + esac
20 + done
13 21
14 22 # Main application flow
15 23 function main {
@@ -34,7 +42,8 @@ function main {
34 42 echo "NOTICE: 1GB free space on '$path' is required to perform the benchmark."
35 43 echo -n "Are you ready to start a robust IO benchmark against '$path' ?"; read answer
36 44 if [ "$answer" != "${answer#[Yy]}" ]; then
37 - echo "Great! Starting benchmark now!";
45 + echo "Great! Starting benchmark now!"
46 + echo "------------------------------"
38 47 else
39 48 echo "Ok, cancelled!"
40 49 exit 0
@@ -47,7 +56,7 @@ function main {
47 56 fio_speedtest
48 57 elif [ "$option" == "" ]; then
49 58 # If fio is installed, use it, else use dd
50 - echo ""
59 + [ "$simple" != true ] && echo ""
51 60 if ! command -v fio &> /dev/null; then
52 61 dd_speedtest
53 62 else
@@ -56,6 +65,26 @@ function main {
56 65 fi
57 66 }
58 67
68 + function print_result {
69 + # Print a single fio test result, either as the full "Run status group"
70 + # line or, when --simple is given, as a compact aligned "Label value" row.
71 + # The simple value is taken from the parenthetical (MB/s) figure that
72 + # follows the first bw= value in fio's output.
73 + local label="$1"
74 + local output="$2"
75 + local status
76 + status=$(echo " - $output " | /usr/bin/grep -A1 'Run status group' | tail -n1)
77 + if [ "$simple" == true ]; then
78 + local value
79 + # Grab the parenthetical (MB/s) figure after the first bw=, then put a
80 + # space between the number and the unit, eg "98.4MB/s" -> "98.4 MB/s".
81 + value=$(echo "$status" | /usr/bin/grep -oP 'bw=\S+\s+\(\K[^)]+' | sed -E 's/([0-9.]+)([A-Za-z])/\1 \2/')
82 + printf "%-28s%s\n" "$label" "$value"
83 + else
84 + echo "$status"
85 + fi
86 + }
87 +
59 88 function fio_write_single_random_4k {
60 89 # Single 4k Random Writes
61 90
@@ -88,8 +117,7 @@ function fio_write_single_random_4k {
88 117 # --iodepth=1 this is how deep we're willing to try to stack commands in the OS's queue. Since we set this to 1, this is effectively pretty much the same thing as the sync IO engine—we're only asking for a single operation at a time, and the OS has to acknowledge receipt of every operation we ask for before we can ask for another. (It does not have to satisfy the request itself before we ask it to do more operations, it just has to acknowledge that we actually asked for it.)
89 118 # --runtime=15 --time_based Run and even if we complete sooner, just start over again and keep going until 60 seconds is up.
90 119 # --end_fsync=1 After all operations have been queued, keep the timer going until the OS reports that the very last one of them has been successfully completed—ie, actually written to disk.
91 - echo ""
92 - echo "Single 4K Random Writes (size=1G, time=15sec, jobs=1, iodepth=1)"
120 + [ "$simple" != true ] && { echo ""; echo "Single 4K Random Writes (size=1G, time=15sec, jobs=1, iodepth=1)"; }
93 121 x=`sudo fio \
94 122 --name=fio-write-random-4k \
95 123 --directory=$path \
@@ -101,8 +129,8 @@ function fio_write_single_random_4k {
101 129 --iodepth=1 \
102 130 --time_based --runtime=15 \
103 131 --end_fsync=1`
104 - echo " - $x " | /usr/bin/grep -A1 'Run status group' | tail -n1
105 -
132 + print_result "Single 4K Random Writes" "$x"
133 +
106 134 # Cleanup my test files
107 135 rm -rf $path/fio-write-random-4k*
108 136 }
@@ -143,8 +171,7 @@ function fio_write_parallel_random_64k {
143 171 # physical media stripe at a time—or a garbage collection or other maintenance
144 172 # operation at the SSD firmware level needs to run briefly in the background,
145 173 # slowing things down.
146 - echo ""
147 - echo "Parallel 64K Random Writes (size=1G, time=15sec, jobs=16, iodepth=16)"
174 + [ "$simple" != true ] && { echo ""; echo "Parallel 64K Random Writes (size=1G, time=15sec, jobs=16, iodepth=16)"; }
148 175 x=`sudo fio \
149 176 --name=fio-write-random-64k \
150 177 --directory=$path \
@@ -156,7 +183,7 @@ function fio_write_parallel_random_64k {
156 183 --iodepth=16 \
157 184 --time_based --runtime=15 \
158 185 --end_fsync=1`
159 - echo " - $x " | /usr/bin/grep -A1 'Run status group' | tail -n1
186 + print_result "Parallel 64K Random Writes" "$x"
160 187
161 188 # Cleanup my test files
162 189 rm -rf $path/fio-write-random-64k*
@@ -201,8 +228,7 @@ function fio_write_single_sequential_1m {
201 228 # here is that you understand both what you want to test, and how to test
202 229 # it accurately.
203 230
204 - echo ""
205 - echo "Single 1M Sequential Writes (size=1G, time=15sec, jobs=1, iodepth=1)"
231 + [ "$simple" != true ] && { echo ""; echo "Single 1M Sequential Writes (size=1G, time=15sec, jobs=1, iodepth=1)"; }
206 232 x=`sudo fio \
207 233 --name=fio-write-random-1m \
208 234 --directory=$path \
@@ -214,7 +240,7 @@ function fio_write_single_sequential_1m {
214 240 --iodepth=1 \
215 241 --time_based --runtime=15 \
216 242 --end_fsync=1`
217 - echo " - $x " | /usr/bin/grep -A1 'Run status group' | tail -n1
243 + print_result "Single 1M Sequential Writes" "$x"
218 244
219 245 # Cleanup my test files
220 246 rm -rf $path/fio-write-random-1m*
@@ -223,8 +249,7 @@ function fio_write_single_sequential_1m {
223 249 function fio_read_sequential_1m {
224 250 # Sequential Parallel Reads
225 251
226 - echo ""
227 - echo "Sequential 4x 1M Reads"
252 + [ "$simple" != true ] && { echo ""; echo "Sequential 4x 1M Reads"; }
228 253 x=`sudo fio \
229 254 --name=fio-read-sequential-1m \
230 255 --directory=$path \
@@ -241,15 +266,14 @@ function fio_read_sequential_1m {
241 266 --group_reporting=1 \
242 267 --iodepth_batch_submit=64 \
243 268 --iodepth_batch_complete_max=64`
244 - echo " - $x " | /usr/bin/grep -A1 'Run status group' | tail -n1
269 + print_result "Sequential 4x 1M Reads" "$x"
245 270 rm -rf $path/fio-read-sequential-1m*
246 271 }
247 272
248 273 function fio_read_random_4k {
249 274 # Random 4k Reads
250 275
251 - echo ""
252 - echo "Random 4k Reads"
276 + [ "$simple" != true ] && { echo ""; echo "Random 4k Reads"; }
253 277 x=`sudo fio \
254 278 --name=fio-read-random-4k \
255 279 --directory=$path \
@@ -266,7 +290,7 @@ function fio_read_random_4k {
266 290 --group_reporting=1 \
267 291 --iodepth_batch_submit=256 \
268 292 --iodepth_batch_complete_max=256`
269 - echo " - $x " | /usr/bin/grep -A1 'Run status group' | tail -n1
293 + print_result "Random 4k Reads" "$x"
270 294 rm -rf $path/fio-read-random-4k*
271 295 }
272 296
@@ -331,6 +355,10 @@ function usage {
331 355 echo " This will force DD"
332 356 echo " ./speedtest-hd /mnt/somedisk --dd"
333 357 echo " ./speedtest-hd . --dd"
358 + echo ""
359 + echo " Add --simple (FIO only) for a compact, aligned summary of MB/s values"
360 + echo " ./speedtest-hd . --simple"
361 + echo " ./speedtest-hd . --fio --simple"
334 362 exit 0
335 363 }
336 364

mreschke revised this gist 3 months ago · 29786f9

No changes

mreschke revised this gist 3 months ago · 8df4d7e

1 file changed, 338 insertions

speedtest-hd.sh (file created)

Diff is too large to be shown