On Sat, 2015-08-29 at 12:43 +0200, Ahmed S. Darwish wrote: > Add shell script to sample PulseAudio memory usage (VmSize, > Private_Dirty + Shared_Dirty) while increasing the number of connected > 'paplay' clients over time. > > Linux kernel /proc/$PID/smaps fields Private and Shared_Dirty are used > to accurately measure the total size of used dirty pages over time. > This shall be useful for benchmarking the PA daemon's memory while > introducing new features like the exclusively per-client SHM access. > > Also add an empty benchmarks collection directory 'benchmarks/'. All > output from the benchmarking tools shall be saved in this place, with > timestamps and symbolic links to the newest versions. > > Signed-off-by: Ahmed S. Darwish <darwish.07 at gmail.com> > --- > scripts/benchmark_memory_usage.sh | 87 +++++++++++++++++++++++++++++++++++++++ > scripts/benchmarks/.gitignore | 10 +++++ > scripts/benchmarks/README | 4 ++ > 3 files changed, 101 insertions(+) > create mode 100755 scripts/benchmark_memory_usage.sh > create mode 100644 scripts/benchmarks/.gitignore > create mode 100644 scripts/benchmarks/README Thanks! This seems like a useful script. I had a few problems, which I'll point out below. > diff --git a/scripts/benchmark_memory_usage.sh b/scripts/benchmark_memory_usage.sh > new file mode 100755 > index 0000000..3687793 > --- /dev/null > +++ b/scripts/benchmark_memory_usage.sh > @@ -0,0 +1,87 @@ > +#!/bin/bash > +# > +# 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. > +# > + > +_basename=$(basename $0) > +PROMPT="\033[1m[$_basename]\033[0m" > +error() { > + echo -e "$PROMPT: ** $1" >&2; exit -1 > +} > +msg() { > + echo -e "$PROMPT: $1" > +} > + > +_absolute_dirname="$(dirname `which $0`)" I guess the purpose of "which" is to get the absolute path of the script, but it doesn't do that at least on my machine. "readlink -f $0" should work better. > +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_PLAY=${PA_HOME}/src/paplay paplay doesn't exist in the source tree. paplay is a symlink to pacat, and the symlink is created only during installation. I would suggest using pacat here, but pacat assumes that the file format is raw by default, and the --file-format option doesn't seem to allow telling pacat to autodetect the file format. I think the --file-format option should be modified to support "auto" as one of the recognized values. > +PA_FLAGS="-n -F ${PA_HOME}/src/default.pa -p ${PA_HOME}/src/" > + > +OUTPUT_DIR=${PA_HOME}/scripts/benchmarks > +OUTPUT_FILE=${OUTPUT_DIR}/MEMORY-USAGE-`date -Iseconds`.txt > +SYMLINK_LATEST_OUTPUT_FILE=${OUTPUT_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_PLAY" ] || error "$PA_PLAY 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" > + > +echo "# ClientCount VmSize (KiB) DirtyRSS (KiB)" >$OUTPUT_FILE > + > +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" > + > +export PULSE_LOG=1 PULSE_LOG_COLORS= PULSE_LOG_META= > + > +msg "Starting PulseAudio daemon" > +$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 > + > +msg "Starting PulseAudio clients" > +_n=0; > +while true; do > + [ "$_n" -le "$MAX_CLIENTS" ] || break > + > + _vmsize=`ps -o vsize= $_pid` > + _drss=`awk '/(Shared|Private)_Dirty:/{ sum += $2 } END { print sum }' /proc/$_pid/smaps` This failed for me at first, because I had pulseaudio already running, so starting the test instance failed, and therefore /proc/$_pid/smaps didn't exist. I think it would be a good idea to fail early in the script with a clear error message if pulseaudio is already running. -- Tanu