[pulseaudio-discuss] Null sink and its monitor cause high CPU usage in headless environment
Georg Chini
georg at chini.tk
Mon Oct 31 19:20:29 UTC 2022
Hi,
the first null-sink is configured for 500 usec latency, that causes the
high CPU load.
If you use something higher, say 5 msec, the load will go down
significantly. Also,
you don't have module-suspend-on-idle loaded, which means that the sinks are
active all the time, even if they are not used.
Regards
Georg
On 31.10.22 19:32, Tudor Zaharia wrote:
> Hello,
>
> <sorry for sending this again; the original message is still awaiting moderation because of the large size caused by rich html format. I can't seem to be able to cancel the moderation anymore>
>
> I'm posting here after reading this thread: https://www.mail-archive.com/pulseaudio-discuss@lists.freedesktop.org/msg21644.html Unfortunately I couldn't find a solution for my case there.
>
> The problem:
> I am seeing high CPU usage caused by pulseaudio in a headless environment where the only module that I need is the null sink. Moreover, the high CPU symptom is noticeable even when there is no audio IO performed by the client, i.e. the client app is not reading nor writing anything to/from the null sinks and its monitors.
>
> A. The setup:
>
> 1. Pulseaudio:
>
> * client.conf:
> default-server = unix:/pa/pulse-socket
> autospawn=no
> daemon-binary = /bin/true
> enable-shm = false
>
> * default.pa:
> load-module module-null-sink sink_name=emulator_out sink_properties=device.description=emulator_out format=s16le rate=48000 channels=2 channel_map=front-left,front-right
> load-module module-null-sink sink_name=emulator_in sink_properties=device.description=emulator_in format=s16le rate=48000 channels=2 channel_map=front-left,front-right
>
> * daemon.conf:
> ; daemonize = no
> ; fail = yes
> ; allow-module-loading = yes
> ; allow-exit = yes
> ; use-pid-file = yes
> ; system-instance = yes
> ; local-server-type = user
> ; enable-shm = yes
> ; enable-memfd = yes
> ; shm-size-bytes = 0 # setting this 0 will use the system-default, usually 64 MiB
> ; lock-memory = no
> ; cpu-limit = no
>
> ; high-priority = yes
> ; nice-level = -11
>
> ; realtime-scheduling = yes
> ; realtime-priority = 5
>
> ; exit-idle-time = 20
> ; scache-idle-time = 20
>
> ; dl-search-path = (depends on architecture)
>
> ; load-default-script-file = yes
> ; default-script-file = /etc/pulse/default.pa
>
> ; log-target = auto
> ; log-level = notice
> ; log-meta = no
> ; log-time = no
> ; log-backtrace = 0
>
> ; remixing-use-all-sink-channels = yes
> ; remixing-produce-lfe = no
> ; remixing-consume-lfe = no
> ; lfe-crossover-freq = 0
>
> ; flat-volumes = no
>
> ; rescue-streams = yes
>
> ; rlimit-fsize = -1
> ; rlimit-data = -1
> ; rlimit-stack = -1
> ; rlimit-core = -1
> ; rlimit-as = -1
> ; rlimit-rss = -1
> ; rlimit-nproc = -1
> ; rlimit-nofile = 256
> ; rlimit-memlock = -1
> ; rlimit-locks = -1
> ; rlimit-sigpending = -1
> ; rlimit-msgqueue = -1
> ; rlimit-nice = 31
> ; rlimit-rtprio = 9
> ; rlimit-rttime = 200000
>
> ; default-sample-format = s16le
> ; default-sample-channels = 2
> ; default-channel-map = front-left,front-right
>
> ; default-fragments = 4
> ; default-fragment-size-msec = 25
>
> ; enable-deferred-volume = yes
> deferred-volume-safety-margin-usec = 1
> ; deferred-volume-extra-delay-usec = 0
>
> ; avoid-resampling = true
> default-sample-rate = 48000
> alternate-sample-rate = 24000
> enable-remixing = no
> resample-method = trivial
>
> * In order to completely isolate the pulseaudio server, I have made a Docker image based on bitnami/minideb:stretch where I installed pulseaudio. Then I start the container by mapping a volume on the host to enable socket communication between the host and the guest:
> $ docker run --name pa --rm --privileged -v /tmp/pa-docker:/pa mypa
>
>
> 2. Start Android Emulator (this is the pulseaudio client that will connect to the above setup server):
>
> $ QEMU_PA_SERVER=unix:/tmp/pa-docker/pulse-socket QEMU_AUDIO_DRV=pa QEMU_PA_SINK=emulator_out QEMU_PA_SOURCE=emulator_in.monitor QEMU_AUDIO_DAC_FIXED_FREQ=48000 QEMU_AUDIO_ADC_FIXED_FREQ=48000 ANDROID_SDK_ROOT=~/Android/Sdk ~/Android/Sdk/emulator/emulator -verbose @Pixel_2_API_29
>
> This runs on the host but connects to the guest through the socket on the mapped volume (QEMU_PA_SERVER).
>
> B. The behavior
>
> The setup above works fine, but pulseaudio uses anywhere between 6% and 15% of the CPU although the emulator is neither outputting any audio, nor reading the virtual microphone. It is basically idle.
>
> $ docker exec -it pa top
>
> Tasks: 2 total, 1 running, 1 sleeping, 0 stopped, 0 zombie
> %Cpu(s): 3.2 us, 9.8 sy, 0.0 ni, 87.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
> KiB Mem : 65784824 total, 31055920 free, 16851640 used, 17877264 buff/cache
> KiB Swap: 2097148 total, 2097148 free, 0 used. 47699540 avail Mem
>
> PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
> 1 root 9 -11 326868 6896 5892 S 10.3 0.0 0:50.69 pulseaudio
> 16 root 20 0 43148 3240 2732 R 0.0 0.0 0:00.06 top
>
> Pulseaudio pacmd list output:
>
> $ docker exec -it pa pacmd list
> Memory blocks currently allocated: 4, size: 64.1 KiB.
> Memory blocks allocated during the whole lifetime: 12667, size: 4.5 MiB.
> Memory blocks imported from other processes: 0, size: 0 B.
> Memory blocks exported to other processes: 0, size: 0 B.
> Total sample cache size: 0 B.
> Default sample spec: s16le 2ch 48000Hz
> Default channel map: front-left,front-right
> Default sink name: emulator_out
> Default source name: emulator_out.monitor
> Memory blocks of type POOL: 4 allocated/12667 accumulated.
> Memory blocks of type POOL_EXTERNAL: 0 allocated/0 accumulated.
> Memory blocks of type APPENDED: 0 allocated/0 accumulated.
> Memory blocks of type USER: 0 allocated/0 accumulated.
> Memory blocks of type FIXED: 0 allocated/0 accumulated.
> Memory blocks of type IMPORTED: 0 allocated/0 accumulated.
> 4 module(s) loaded.
> index: 0
> name: <module-null-sink>
> argument: <sink_name=emulator_out sink_properties=device.description=emulator_out format=s16le rate=48000 channels=2 channel_map=front-left,front-right>
> used: 1
> load once: no
> properties:
> module.author = "Lennart Poettering"
> module.description = "Clocked NULL sink"
> module.version = "10.0"
> index: 1
> name: <module-null-sink>
> argument: <sink_name=emulator_in sink_properties=device.description=emulator_in format=s16le rate=48000 channels=2 channel_map=front-left,front-right>
> used: 1
> load once: no
> properties:
> module.author = "Lennart Poettering"
> module.description = "Clocked NULL sink"
> module.version = "10.0"
> index: 2
> name: <module-native-protocol-unix>
> argument: <auth-anonymous=1 socket=/pa/pulse-socket>
> used: -1
> load once: no
> properties:
> module.author = "Lennart Poettering"
> module.description = "Native protocol (UNIX sockets)"
> module.version = "10.0"
> index: 3
> name: <module-cli-protocol-unix>
> argument: <>
> used: -1
> load once: no
> properties:
> module.author = "Lennart Poettering"
> module.description = "Command line interface protocol (UNIX sockets)"
> module.version = "10.0"
> 2 sink(s) available.
> * index: 0
> name: <emulator_out>
> driver: <module-null-sink.c>
> flags: DECIBEL_VOLUME LATENCY FLAT_VOLUME DYNAMIC_LATENCY
> state: RUNNING
> suspend cause:
> priority: 1000
> volume: front-left: 65536 / 100% / 0.00 dB, front-right: 65536 / 100% / 0.00 dB
> balance 0.00
> base volume: 65536 / 100% / 0.00 dB
> volume steps: 65537
> muted: no
> current latency: 0.43 ms
> max request: 0 KiB
> max rewind: 0 KiB
> monitor source: 0
> sample spec: s16le 2ch 48000Hz
> channel map: front-left,front-right
> Stereo
> used by: 1
> linked by: 1
> configured latency: 0.50 ms; range is 0.50 .. 2000.00 ms
> module: 0
> properties:
> device.description = "emulator_out"
> device.class = "abstract"
> device.icon_name = "audio-card"
> index: 1
> name: <emulator_in>
> driver: <module-null-sink.c>
> flags: DECIBEL_VOLUME LATENCY FLAT_VOLUME DYNAMIC_LATENCY
> state: IDLE
> suspend cause:
> priority: 1000
> volume: front-left: 65536 / 100% / 0.00 dB, front-right: 65536 / 100% / 0.00 dB
> balance 0.00
> base volume: 65536 / 100% / 0.00 dB
> volume steps: 65537
> muted: no
> current latency: 8.77 ms
> max request: 1 KiB
> max rewind: 1 KiB
> monitor source: 1
> sample spec: s16le 2ch 48000Hz
> channel map: front-left,front-right
> Stereo
> used by: 0
> linked by: 1
> configured latency: 10.00 ms; range is 0.50 .. 2000.00 ms
> module: 1
> properties:
> device.description = "emulator_in"
> device.class = "abstract"
> device.icon_name = "audio-card"
> 2 source(s) available.
> * index: 0
> name: <emulator_out.monitor>
> driver: <module-null-sink.c>
> flags: DECIBEL_VOLUME LATENCY DYNAMIC_LATENCY
> state: IDLE
> suspend cause:
> priority: 1000
> volume: front-left: 65536 / 100% / 0.00 dB, front-right: 65536 / 100% / 0.00 dB
> balance 0.00
> base volume: 65536 / 100% / 0.00 dB
> volume steps: 65537
> muted: no
> current latency: 0.00 ms
> max rewind: 0 KiB
> sample spec: s16le 2ch 48000Hz
> channel map: front-left,front-right
> Stereo
> used by: 0
> linked by: 0
> configured latency: 2000.00 ms; range is 0.50 .. 2000.00 ms
> monitor_of: 0
> module: 0
> properties:
> device.description = "Monitor of emulator_out"
> device.class = "monitor"
> device.icon_name = "audio-input-microphone"
> index: 1
> name: <emulator_in.monitor>
> driver: <module-null-sink.c>
> flags: DECIBEL_VOLUME LATENCY DYNAMIC_LATENCY
> state: IDLE
> suspend cause:
> priority: 1000
> volume: front-left: 65536 / 100% / 0.00 dB, front-right: 65536 / 100% / 0.00 dB
> balance 0.00
> base volume: 65536 / 100% / 0.00 dB
> volume steps: 65537
> muted: no
> current latency: 0.00 ms
> max rewind: 1 KiB
> sample spec: s16le 2ch 48000Hz
> channel map: front-left,front-right
> Stereo
> used by: 0
> linked by: 1
> configured latency: 10.00 ms; range is 0.50 .. 2000.00 ms
> monitor_of: 1
> module: 1
> properties:
> device.description = "Monitor of emulator_in"
> device.class = "monitor"
> device.icon_name = "audio-input-microphone"
> 2 client(s) logged in.
> index: 0
> driver: <protocol-native.c>
> owner module: 2
> properties:
> application.name = "unix:/tmp/pa-docker/pulse-socket"
> native-protocol.peer = "UNIX socket client"
> native-protocol.version = "33"
> application.process.id = "23931"
> application.process.user = "tudor"
> application.process.host = "machine"
> application.process.binary = "qemu-system-x86_64"
> application.language = "C"
> window.x11.display = ":1"
> application.process.machine_id = "c6ba133539f0416791786992742aa11c"
> index: 3
> driver: <cli.c>
> owner module: 3
> properties:
> application.name = "UNIX socket client"
> 0 card(s) available.
> 1 sink input(s) available.
> index: 0
> driver: <protocol-native.c>
> flags:
> state: DRAINED
> sink: 0 <emulator_out>
> volume: front-left: 65536 / 100% / 0.00 dB, front-right: 65536 / 100% / 0.00 dB
> balance 0.00
> muted: no
> current latency: 0.00 ms
> requested latency: 0.50 ms
> sample spec: s16le 2ch 48000Hz
> channel map: front-left,front-right
> Stereo
> resample method: (null)
> module: 2
> client: 0 <unix:/tmp/pa-docker/pulse-socket>
> properties:
> media.name = "qemu"
> application.name = "unix:/tmp/pa-docker/pulse-socket"
> native-protocol.peer = "UNIX socket client"
> native-protocol.version = "33"
> application.process.id = "23931"
> application.process.user = "tudor"
> application.process.host = "machine"
> application.process.binary = "qemu-system-x86_64"
> application.language = "C"
> window.x11.display = ":1"
> application.process.machine_id = "c6ba133539f0416791786992742aa11c"
> 1 source output(s) available.
> index: 0
> driver: <protocol-native.c>
> flags: START_CORKED
> state: CORKED
> source: 1 <emulator_in.monitor>
> volume: front-left: 65536 / 100% / 0.00 dB, front-right: 65536 / 100% / 0.00 dB
> balance 0.00
> muted: no
> current latency: 0.00 ms
> requested latency: 10.00 ms
> sample spec: s16le 2ch 48000Hz
> channel map: front-left,front-right
> Stereo
> resample method: (null)
> owner module: 2
> client: 0 <unix:/tmp/pa-docker/pulse-socket>
> properties:
> media.name = "qemu"
> application.name = "unix:/tmp/pa-docker/pulse-socket"
> native-protocol.peer = "UNIX socket client"
> native-protocol.version = "33"
> application.process.id = "23931"
> application.process.user = "tudor"
> application.process.host = "machine"
> application.process.binary = "qemu-system-x86_64"
> application.language = "C"
> window.x11.display = ":1"
> application.process.machine_id = "c6ba133539f0416791786992742aa11c"
> 0 cache entrie(s) available.
>
> Other considerations:
> In an attempt to try to identify the cause of the problem, I have built pulseaudio from source with valgrind support and run it with the `callgrind` tool. Unfortunately I have reached my limits when trying to correlate that output with the high CPU usage.
>
> Android Emulator is not the only application that I've tried with this setup and seen the same behavior. I used it as an example here because I thought it is easier to understand what is going on.
>
> My system has an i7-9700 CPU with plenty of RAM and running Ubuntu 20.04. And in any case, like I said the emulator is idle concerning audio input/output.
> Do you know why I'm seeing this high CPU usage and how I could fix it?
>
> Thanks,
> Tudor
More information about the pulseaudio-discuss
mailing list