diff options
Diffstat (limited to '')
-rwxr-xr-x | scripts/benchmark_memory_usage.sh | 133 | ||||
-rw-r--r-- | scripts/benchmarks/.gitignore | 10 | ||||
-rw-r--r-- | scripts/benchmarks/README | 4 | ||||
-rw-r--r-- | scripts/plot_memory_usage.gp | 63 |
4 files changed, 210 insertions, 0 deletions
diff --git a/scripts/benchmark_memory_usage.sh b/scripts/benchmark_memory_usage.sh new file mode 100755 index 0000000..f053d7e --- /dev/null +++ b/scripts/benchmark_memory_usage.sh @@ -0,0 +1,133 @@ +#!/bin/bash + +# This file is part of PulseAudio. +# +# Copyright 2015 Ahmed S. Darwish <darwish.07@gmail.com> +# +# PulseAudio is free software; you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# PulseAudio is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with PulseAudio; if not, see <http://www.gnu.org/licenses/>. + +# +# Measure PulseAudio memory usage (VmSize, Private+Shared_Dirty) +# while increasing the number of connected clients over time. +# +# To avoid premature client exits, please ensure giving a long +# wave file as the script's first parameter. +# + +_bold="\x1B[1m" +_error="\x1B[1;31m" +_reset="\x1B[0m" + +BASENAME=$(basename $0) +PROMPT="${_bold}[$BASENAME]${_reset}" +error() { + echo -e "$PROMPT: ** Error: ${_error}$1${_reset}" >&2; exit -1 +} +msg() { + echo -e "$PROMPT: $1" +} + +_absolute_dirname="$(dirname `readlink -f $0`)" +PA_HOME="${_absolute_dirname%/scripts}" +[ -d "$PA_HOME/src" -a -d "$PA_HOME/scripts" ] || + error "This script can only be executed from PulseAudio source tree" + +PA=${PA_HOME}/src/pulseaudio +PA_CAT=${PA_HOME}/src/pacat +PA_PLAY=${PA_HOME}/src/paplay +PA_FLAGS="-n -F ${PA_HOME}/src/default.pa -p ${PA_HOME}/src/" + +[ -L "$PA_PLAY" ] || ln -sf .libs/lt-pacat $PA_PLAY +PA_PLAY_PROCESS_NAME="paplay" + +SCRIPTS_DIR=${PA_HOME}/scripts +BENCHMARKS_DIR=${SCRIPTS_DIR}/benchmarks +GNUPLOT_SCRIPT=${SCRIPTS_DIR}/plot_memory_usage.gp +OUTPUT_FILE=${BENCHMARKS_DIR}/memory-usage-`date -Iseconds`.txt +SYMLINK_LATEST_OUTPUT_FILE=${BENCHMARKS_DIR}/memory-usage-LATEST.txt + +MAX_CLIENTS=30 + +[ -e "$PA" ] || error "$PA does not exist. Compile PulseAudio tree first." +[ -x "$PA" ] || error "$PA cannot be executed" +[ -x "$PA_CAT" ] || error "$PA_CAT cannot be executed" + +AUDIO_FILE="$1" +[ -n "$AUDIO_FILE" ] || error "Usage: $BASENAME AUDIO_FILE" +[ -e "$AUDIO_FILE" ] || error "$AUDIO_FILE does not exist" +[ -f "$AUDIO_FILE" ] || error "$AUDIO_FILE is not a regular file" + +$PA --check >/dev/null 2>&1 +[ "$?" -ne "0" ] || { + msg "A PulseAudio daemon is already running on your system" + msg "To use this script, please do the following first:" + msg " 1. Add autospawn=no to $HOME/.pulse/client.conf" + msg " 2. Kill current daemon instance using 'pulseaudio --kill'" + error "Failed to start PulseAudio daemon" +} + +msg "Hello. Benchmarking PulseAudio daemon memory usage over time" + +# Check Linux Kernel's Documentation/sysctl/vm.txt for details. +msg "Ensuring consistent results by dropping all VM caches!" +sudo bash -c "sync && echo 3 >/proc/sys/vm/drop_caches" + +msg "Starting PulseAudio daemon" +PULSE_LOG=0 PULSE_LOG_COLORS= PULSE_LOG_META= $PA $PA_FLAGS & +_pid=$! + +# Give PA daemon time to initialize everything and vacuum. We want +# to make the _starting_ dirty RSS memory usage (0 clients) as +# equivalent as possible for multiple trials. +sleep 12 + +$PA --check >/dev/null 2>&1 +[ "$?" -eq "0" ] || error "Failed to start PulseAudio daemon" + +echo "# ClientCount VmSize (KiB) DirtyRSS (KiB)" >$OUTPUT_FILE + +msg "Starting PulseAudio clients" +_i=1; +while true; do + [ "$_i" -le "$MAX_CLIENTS" ] || break + + _vmsize=`ps -o vsize= $_pid` + _drss=`awk '/(Shared|Private)_Dirty:/{ sum += $2 } END { print sum }' /proc/$_pid/smaps` + [ "$?" -eq "0" ] || error "Error sampling PulseAudio RSS memory usage" + + echo " $_i $_vmsize $_drss" >>$OUTPUT_FILE + + $PA_PLAY $AUDIO_FILE 2>/dev/null & + _i=$((_i + 1)) + + sleep 1 +done +msg "Finished starting ${MAX_CLIENTS} PulseAudio clients over time" + +_n_clients_still_alive=$(ps -C $PA_PLAY_PROCESS_NAME --no-headers | wc -l) +[ "$_n_clients_still_alive" -ge "$MAX_CLIENTS" ] || { + msg "You did not provide a long-enough wave file for clients to play" + msg "Only $_n_clients_still_alive clients are now active; expected $MAX_CLIENTS" + error "Please provide a large wave file (~ $((MAX_CLIENTS*2))s) then redo the benchmarks" +} + +msg "Killing PulseAudio daemon" +$PA --kill >/dev/null 2>&1 + +rm -f $SYMLINK_LATEST_OUTPUT_FILE +ln -s $OUTPUT_FILE $SYMLINK_LATEST_OUTPUT_FILE + +msg "Sampling daemon memory usage done!" +msg "Check the results at $SYMLINK_LATEST_OUTPUT_FILE" +msg "Plot these results using 'gnuplot $GNUPLOT_SCRIPT'" diff --git a/scripts/benchmarks/.gitignore b/scripts/benchmarks/.gitignore new file mode 100644 index 0000000..612f79e --- /dev/null +++ b/scripts/benchmarks/.gitignore @@ -0,0 +1,10 @@ +# +# Benchmarks directory .gitignore +# + +# Ignore everything here .. +* + +# Except these files +!README +!.gitignore diff --git a/scripts/benchmarks/README b/scripts/benchmarks/README new file mode 100644 index 0000000..d935b0d --- /dev/null +++ b/scripts/benchmarks/README @@ -0,0 +1,4 @@ +This is an empty directory for collecting users PulseAudio daemon +performance benchmarks, as created by the tools under `scripts/' . + +Please do not commit any file here except this README and .gitignore. diff --git a/scripts/plot_memory_usage.gp b/scripts/plot_memory_usage.gp new file mode 100644 index 0000000..33cc4e1 --- /dev/null +++ b/scripts/plot_memory_usage.gp @@ -0,0 +1,63 @@ + +# This file is part of PulseAudio. +# +# Copyright 2015 Ahmed S. Darwish <darwish.07@gmail.com> +# +# PulseAudio is free software; you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# PulseAudio is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with PulseAudio; if not, see <http://www.gnu.org/licenses/>. + +# +# PulseAudio memory usage plotting script +# +# Before invocation, generate necessary data by running the +# 'benchmark_memory_usage.sh' bash script. Afterwards, you can plot +# such data by running: +# +# gnuplot plot_memory_usage.gp +# +# Note! To avoid scaling issues, memory is plotted in a "double y axis" +# form, with VM usage on the left, and dirty RSS memory usage on the +# right. The scales are different. +# + +# Print our user messages to the stdout +set print "-" + +benchDir = system('dirname ' .ARG0) .'/benchmarks/' +inputFile = benchDir ."memory-usage-LATEST.txt" +outputFile = benchDir ."pulse-memory-usage.png" + +set title "PulseAudio Memory Usage Over Time" +set xlabel "Number of councurrent 'paplay' clients" + +set ylabel "Virtual memory consumption (GiB)" +set y2label "Dirty RSS consumption (MiB)" +set ytics nomirror +set y2tics + +# Finer granulrity for x-axis ticks ... +set xtics 1,1 +set grid + +# Use Cairo's PNG backend. This produce images which are way +# better-rendered than the barebone classical png backend +set terminal pngcairo enhanced size 1000,768 font 'Verdana,10' +set output outputFile + +print "Plotting data from input file: ", inputFile +print "..." + +plot inputFile using 1:($2/1024/1024) title "VmSize" axes x1y1 with linespoints, \ + inputFile using 1:($3/1024) title "Dirty RSS" axes x1y2 with linespoints + +print "Done! Check our performance at: ", outputFile |