[pulseaudio-discuss] [PATCH 1/2] scripts: Introduce helper utility benchmark_memory_usage.sh

Tanu Kaskinen tanuk at iki.fi
Thu Sep 10 07:02:28 PDT 2015


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


More information about the pulseaudio-discuss mailing list