Re: Null sink and its monitor cause high CPU usage in headless environment

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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@xxxxxxxxxxxxxxxxxxxxx/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





[Index of Archives]     [Linux Audio Users]     [AMD Graphics]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux