Skip to content

Commit

Permalink
utils: Add kernel_size_time.sh to measure size and boot time
Browse files Browse the repository at this point in the history
This is what I've been using to measure size and execution times for
a test command (based on muvm) for the previous patches. It's made to
be used in a rebase script, for example:

  x ./utils/kernel_size_time.sh
  pick 12181bf config-libkrunfw_x86_64: Disable processor quirks and features we don't need
  x ./utils/kernel_size_time.sh
  pick 5c5badc config-libkrunfw_x86_64: Drop power management features and cpufreq
  x ./utils/kernel_size_time.sh

it's a bit bigger than what I wanted because of the time -p trick:
nowadays most distributions don't ship /usr/bin/time (at least by
default), but many shells skip support for the POSIX compatibility
mode (-p, which simplifies calculations) in their 'time' built-in,
so, if we need it, we need to re-execute under Bash (assuming it's
not the default non-interactive shell).

Signed-off-by: Stefano Brivio <[email protected]>
  • Loading branch information
sbrivio-rh authored and slp committed Feb 11, 2025
1 parent 5122346 commit 034cbbf
Showing 1 changed file with 96 additions and 0 deletions.
96 changes: 96 additions & 0 deletions utils/kernel_size_time.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
#!/bin/sh -e
#
# SPDX-License-Identifier: LGPL-2.1-only
#
# utils/kernel_size_time.sh - Check build size, and boot time for given command
#
# Copyright (c) 2025 Red Hat GmbH
# Author: Stefano Brivio <[email protected]>

CONFIG="${CONFIG:-config-libkrunfw_x86_64}"
RUNS=${RUNS:-10}
TIME_CMD="${TIME_CMD:-~/muvm/target/release/muvm --mem=64 --vram=0 -c 0,1 -- true}"
PREV_SIZE_FILE="prev_size"
PREV_TIME_FILE="prev_time"
LOG_FILE="log"

find_time_dash_p() {
REEXEC_BASH=n
if time -p ':'; then
TIME_DASH_P='time -p'
elif command -v /usr/bin/time; then
TIME_DASH_P='/usr/bin/time -p'
elif command -v bash; then
# Simply re-execute under bash to avoid further eval tricks
REEXEC_BASH=y
fi
}

build() {
for KERNELDIR in linux-*/; do
cp "${CONFIG}" "${KERNELDIR}/.config"
done

rm -f linux-*/vmlinux
make clean
make -j$(nproc) || make -j$(($(nproc) / 2)) || make
}

measure_runs() {
export LD_PRELOAD=$(ls $(pwd)/libkrunfw.so.*)
for i in $(seq 1 ${RUNS}); do eval ${TIME_CMD}; done
}

measure() {
NEW_SIZE=$(stat -c %s linux-*/vmlinux)
NEW_TIME="$( eval ${TIME_DASH_P} measure_runs 2>&1 | grep real | tr -dc [:digit:] )5"
}

log() {
BASE_SIZE="$(cat ${PREV_SIZE_FILE} 2>/dev/null || :)"
BASE_TIME="$(cat ${PREV_TIME_FILE} 2>/dev/null || :)"

[ -e "${PREV_SIZE_FILE}" ] || FIRST="y"

echo "$NEW_SIZE" > "${PREV_SIZE_FILE}"
echo "$NEW_TIME" > "${PREV_TIME_FILE}"

git rev-parse HEAD >> ${LOG_FILE}

if [ "${FIRST}" = "y" ]; then
NEW_TIME="$(echo 'scale=0; '$NEW_TIME' / '${RUNS} | bc -l)"
printf "Baseline:
- %i bytes in the uncompressed kernel image
- %i ms (average of ${RUNS} runs) for:
${TIME_CMD}
" $NEW_SIZE $NEW_TIME >> ${LOG_FILE}
exit 0
fi

DIFF_SIZE="$((BASE_SIZE - NEW_SIZE))"
DIFF_TIME="$((BASE_TIME - NEW_TIME))"

DIFF_TIME="$(echo 'scale=0; '$DIFF_TIME' / '${RUNS} | bc -l)"
BASE_TIME="$(echo 'scale=0; '$BASE_TIME' / '${RUNS} | bc -l)"
NEW_TIME="$(echo 'scale=0; '$NEW_TIME' / '${RUNS} | bc -l)"

printf "This saves:
- %i bytes (%i -> %i) in the uncompressed kernel image
- %i ms (%i -> %i, average of ${RUNS} runs) for:
${TIME_CMD}
" $DIFF_SIZE $BASE_SIZE $NEW_SIZE $DIFF_TIME $BASE_TIME $NEW_TIME >> ${LOG_FILE}
}

build
find_time_dash_p >/dev/null 2>&1 || { echo "No implementation of 'time -p', exiting"; exit 1; }

if [ ${REEXEC_BASH} = "y" ]; then
bash $0
else
measure
log
fi

0 comments on commit 034cbbf

Please sign in to comment.