Bash-Funk “performance” module
The following commands are available when this module is loaded:
License
SPDX-FileCopyrightText: © Vegard IT GmbH (https://vegardit.com)
SPDX-License-Identifier: Apache-2.0
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-cpu-count
Usage: -cpu-count [OPTION]...
Prints the number of logical processors.
Options:
--help
Prints this help.
--tracecmd
Enables bash debug mode (set -x).
--selftest
Performs a self-test.
--
Terminates the option list.
Examples:
$ -cpu-count
4
Implementation:
[[ $OSTYPE != "darwin"* ]] && grep processor /proc/cpuinfo | wc -l || sysctl -n hw.logicalcpu
-cpu-perf
Usage: -cpu-perf [OPTION]...
Performs a CPU speed test using 'openssl speed' utilizing all available processors or 'cryptsetup benchmark' / 'dd' for single threaded tests.
Options:
-m, --mode MODE (one of: [openssl-aes128,openssl-aes256,openssl-rsa1024,openssl-rsa2048,openssl-rsa4096,cryptsetup-aes128,cryptsetup-aes256,dd-md5sum,dd-sha256sum,dd-sha512sum])
Select the benchmark mode.
-----------------------------
--help
Prints this help.
--tracecmd
Enables bash debug mode (set -x).
--selftest
Performs a self-test.
--
Terminates the option list.
Examples:
$ -cpu-perf --mode dd-md5sum
1073741824 bytes (1.1 GB, 1.0 GiB) copied, 2.04484 s, 525 MB/s
Implementation:
local _mode=${_mode:-openssl-rsa1024}
case $_mode in
openssl-aes*) openssl speed -multi $(-cpu-count) aes-${_mode#*aes}-cbc ;;
openssl-rsa*) openssl speed -multi $(-cpu-count) ${_mode#*-} ;;
cryptsetup-*) cryptsetup benchmark --cipher aes-cbc --key-size ${_mode#cryptsetup-} ;;
dd-*)
if ! hash dd &>/dev/null; then
echo "-cpu-perf: Required command 'dd' is not available."
return 1
fi
if ! hash ${_mode#dd-} &>/dev/null; then
echo "-cpu-perf: Required command '${_mode#dd-}' is not available."
return 1
fi
[[ $OSTYPE == "darwin"* ]] && local _bs=1m || local _bs=1M
dd if=/dev/zero bs=$_bs count=1024 2> >(head -3 | tail -1) > >(${_mode#dd-} >/dev/null)
;;
esac
-disk-latency
Usage: -disk-latency [OPTION]... [PATH]
Determines disk latency in milliseconds using 'dd'.
Parameters:
PATH (default: '.', directory)
Path where to create the test files.
Options:
--help
Prints this help.
--tracecmd
Enables bash debug mode (set -x).
--selftest
Performs a self-test.
--
Terminates the option list.
Examples:
$ -disk-latency
2.34362 ms disk latency on device /dev/xvda2
$ -disk-latency /tmp
1.46379 ms disk latency on device /dev/xvda1
Implementation:
if hash ioping &>/dev/null; then
ioping -c 1 "$_PATH"
else
if [[ $OSTYPE == "darwin"* ]]; then
local testFile="$(mktemp "$_PATH/XXXXXX")"
else
local testFile="$(mktemp --tmpdir="$_PATH")"
fi
if ! hash dd &>/dev/null; then
echo "-disk-latency: Required command 'dd' or 'ioping' is not available."
return 1
fi
local ddResult
if ddResult=$(set -o pipefail; dd if=/dev/zero "of=$testFile" bs=512 count=1000 oflag=dsync 2>&1 | tail -1 | sed -E 's/.*copied, ([0-9.]+) .+/\1 ms/'); then
rm "$testFile"
echo "$ddResult disk latency on device $(df -P "$_PATH" | tail -1 | cut -d' ' -f1)"
return 0
else
rm "$testFile"
echo $ddResult
return 1
fi
fi
-disk-perf
Usage: -disk-perf [OPTION]... [PATH]
Performs a I/O speed test using 'fio' utilizing all available processors or single-threaded using 'dd'.
Parameters:
PATH (default: '.', directory)
Path where to create the test files.
Options:
-m, --mode MODE (one of: [dd,fio])
Select the benchmark mode.
--size SIZE (integer: 1-?)
Test file size in MB (Default is 2048MB).
-----------------------------
--help
Prints this help.
--tracecmd
Enables bash debug mode (set -x).
--selftest
Performs a self-test.
--
Terminates the option list.
Examples:
$ -disk-perf --mode dd --size 2
Testing single-threaded sequential write performance...
2097152 bytes (2.1 MB, 2.0 MiB) copied, 0.0186709 s, 112 MB/s
Testing single-threaded sequential read performance...
2097152 bytes (2.1 MB, 2.0 MiB) copied, 0.00332485 s, 631 MB/s
Implementation:
local _size=${_size:-2048}
local _mode=${_mode:-fio}
case $_mode in
dd)
if ! hash dd &>/dev/null; then
echo "-disk-perf: Required command 'dd' is not available."
return 1
fi
if [[ $OSTYPE == "darwin"* ]]; then
local testFile=$(mktemp "$_PATH/XXXXXX")
else
local testFile=$(mktemp --tmpdir="$_PATH")
fi
echo "Testing single-threaded sequential write performance..."
dd if=/dev/zero of="${testFile}" bs=1M count=${_size} conv=fdatasync 2>&1 | head -3 | tail -1
echo
echo "Testing single-threaded sequential read performance..."
dd if="${testFile}" of=/dev/null bs=4k 2>&1 | head -3 | tail -1
rm $testFile
;;
*) if ! hash fio &>/dev/null; then
echo "-disk-perf: Required command 'fio' is not available. You can also try with option '--mode dd'."
return 1
fi
if [[ $OSTYPE == "darwin"* ]]; then
local testFile=$(basename $(mktemp -u "$_PATH/XXXXXX"))
else
local testFile=$(basename $(mktemp --dry-run --tmpdir="$_PATH"))
fi
echo "Testing multi-threaded random write performance..."
fio --randrepeat=1 --ioengine=libaio --direct=1 --gtod_reduce=1 --directory="$_PATH" --numjobs $(-cpu-count) --name=$testFile --bs=4k --iodepth=64 --size=${_size}M --readwrite=randwrite
echo
echo "Testing multi-threaded random read performance..."
fio --randrepeat=1 --ioengine=libaio --direct=1 --gtod_reduce=1 --directory="$_PATH" --numjobs $(-cpu-count) --name=$testFile --bs=4k --iodepth=64 --size=${_size}M --readwrite=randread
echo
echo "Testing multi-threaded random read-write (3:1) performance..."
fio --randrepeat=1 --ioengine=libaio --direct=1 --gtod_reduce=1 --directory="$_PATH" --numjobs $(-cpu-count) --name=$testFile --bs=4k --iodepth=64 --size=${_size}M --readwrite=randrw --rwmixread=75
;;
esac
-scp-perf
Usage: -scp-perf [OPTION]... TARGET [SIZE_MB]
Performs an SCP speed test.
Parameters:
TARGET (required)
[user@:]hostname.
SIZE_MB (default: '10', integer: ?-?)
Test file size in MB.
Options:
-i, --identity_file PATH (file)
Path to the private key for public key authentication.
-P, --port PORT (integer: 0-65535)
Ssh port.
-----------------------------
--help
Prints this help.
--tracecmd
Enables bash debug mode (set -x).
--selftest
Performs a self-test.
--
Terminates the option list.
Implementation:
local dataFile=$(mktemp)
local sshOpts=""
if [[ ${_port} ]]; then
sshOpts="$sshOpts -P $_port"
fi
if [[ ${_identity_file} ]]; then
sshOpts="$sshOpts -i $_identity_file"
fi
local _SIZE_MB=${_SIZE_MB:-10}
echo "Generating $_SIZE_MB MB of random data..."
dd if=/dev/urandom bs=1M count=$_SIZE_MB of=$dataFile conv=notrunc
echo
echo "Uploading $_SIZE_MB MB to $_TARGET..."
scp $sshOpts "$dataFile" "$_TARGET:${dataFile}-copy"
echo
echo "Downloading $_SIZE_MB MB from $_TARGET..."
scp $sshOpts "$_TARGET:${dataFile}-copy" "$dataFile"
echo
echo "Removing test data on $_TARGET..."
ssh $sshOpts "$_TARGET" "rm ${dataFile}-copy"
echo "Removing local test data..."
rm $dataFile
-test-all-performance
Usage: -test-all-performance [OPTION]...
Performs a selftest of all functions of this module by executing each function with option '--selftest'.
Options:
--help
Prints this help.
--tracecmd
Enables bash debug mode (set -x).
--selftest
Performs a self-test.
--
Terminates the option list.
Implementation:
-cpu-count --selftest && echo || return 1
-cpu-perf --selftest && echo || return 1
-disk-latency --selftest && echo || return 1
-disk-perf --selftest && echo || return 1
-scp-perf --selftest && echo || return 1