[pulseaudio-discuss] [RFC PATCH] alsa-sink: Reduce hardware pointer update syscalls

Alexander E. Patrakov patrakov at gmail.com
Thu Sep 18 13:31:31 PDT 2014


19.09.2014 02:07, Alexander E. Patrakov wrote:
> 18.09.2014 13:13, David Henningsson wrote:
>> Calling snd_pcm_avail/delay causes a syscall to the kernel, which
>> communicates with the audio hardware, and can therefore be expensive
>> on some cards.
>>
>> By only updating this value after a sleep and after unusual events,
>> we can reduce calls to update the hardware pointer.
>> In particular, if a write goes well, we will now assume that the
>> buffer has been filled up, instead of re-asking the hardware that
>> this is actually the case.
>
> The patch causes an assertion failure on my laptop.
>
> E: [alsa-sink-ALC275 Analog] alsa-sink.c: Assertion 'frames > 0' 
> failed at modules/alsa/alsa-sink.c:651, function mmap_write(). Aborting.
>

This is somehow related to autosuspending the sink. I have worked around 
that by not letting it suspend.

I have tested the performance implications of the patch on my laptop. 
The methodology is:

1. Force the frequency of all CPU cores to 800 MHz
2. In one terminal, run: pulseaudio -k ; perf record ./src/pulseaudio -v
3. In another terminal, run: aplay -f cd -d 60 --period-size=44100 
--buffer-size=88200 /dev/zero ; pulseaudio -k

The test was also repeated with --period-size=441 --buffer-size=882.

In both cases, the "perf report" output is almost identical with and 
without the patch. For brevity, I omit everything below 1%.

For 1s period, without the patch:

# Overhead     Command                   Shared 
Object                                           Symbol
# ........  ..........  .............................. 
...............................................
#
     14.44%  pulseaudio  libasound.so.2.0.0              [.] 
softvol_convert_stereo_vol
      8.51%  pulseaudio  [kernel.kallsyms]               [k] __lock_acquire
      5.12%  pulseaudio  libasound.so.2.0.0              [.] 
snd_pcm_format_little_endian
      2.87%  pulseaudio  [kernel.kallsyms]               [k] lock_release
      1.74%  pulseaudio  [kernel.kallsyms]               [k] lock_acquire
      1.56%  pulseaudio  [kernel.kallsyms]               [k] mark_lock
      1.53%  pulseaudio  ld-2.19.so                      [.] strcmp
      1.51%  pulseaudio  libasound.so.2.0.0              [.] 
snd_pcm_format_cpu_endian
      1.39%  pulseaudio  ld-2.19.so                      [.] do_lookup_x
      1.25%  pulseaudio  libasound.so.2.0.0              [.] 
snd_pcm_format_little_endian at plt
      1.10%  pulseaudio  [kernel.kallsyms]               [k] 
trace_hardirqs_on_caller
      1.03%  pulseaudio  libasound.so.2.0.0              [.] 
snd_pcm_format_cpu_endian at plt

(don't panic! softvol_convert_stereo_vol doesn't eat > 14% of the CPU 
here, it eats 13% of all busy cycles. I.e. other applications that 
happened to be running on this mostly-idle laptop and other PulseAudio 
functions ate 7x more CPU time.)

For 1s period, with the patch:

# Overhead     Command          Shared 
Object                                           Symbol
# ........  ..........  ..................... 
...............................................
#
     13.67%  pulseaudio  libasound.so.2.0.0     [.] 
softvol_convert_stereo_vol
      7.74%  pulseaudio  [kernel.kallsyms]      [k] __lock_acquire
      5.32%  pulseaudio  libasound.so.2.0.0     [.] 
snd_pcm_format_little_endian
      3.41%  pulseaudio  [kernel.kallsyms]      [k] lock_release
      2.48%  pulseaudio  [kernel.kallsyms]      [k] lock_acquire
      2.04%  pulseaudio  ld-2.19.so             [.] do_lookup_x
      1.64%  pulseaudio  [kernel.kallsyms]      [k] mark_lock
      1.39%  pulseaudio  [kernel.kallsyms]      [k] 
trace_hardirqs_on_caller
      1.33%  pulseaudio  libasound.so.2.0.0     [.] 
snd_pcm_format_cpu_endian at plt
      1.23%  pulseaudio  [kernel.kallsyms]      [k] 
trace_hardirqs_off_caller
      1.02%  pulseaudio  ld-2.19.so             [.] strcmp

For 0.01s period, without the patch:

# Overhead     Command                     Shared 
Object                                                 Symbol
# ........  ..........  ................................ 
.....................................................
#
     13.12%  pulseaudio  [kernel.kallsyms]                 [k] 
__lock_acquire
      4.23%  pulseaudio  [kernel.kallsyms]                 [k] lock_release
      2.78%  pulseaudio  [kernel.kallsyms]                 [k] lock_acquire
      1.93%  pulseaudio  [kernel.kallsyms]                 [k] __fget
      1.74%  pulseaudio  [kernel.kallsyms]                 [k] do_sys_poll
      1.61%  pulseaudio  [kernel.kallsyms]                 [k] mark_lock
      1.47%  pulseaudio  libasound.so.2.0.0                [.] 
softvol_convert_stereo_vol
      1.27%  pulseaudio  [kernel.kallsyms]                 [k] 
trace_hardirqs_on_caller

For 0.01s period, with the patch:

# Overhead     Command               Shared 
Object                                           Symbol
# ........  ..........  .......................... 
...............................................
#
     13.03%  pulseaudio  [kernel.kallsyms]           [k] __lock_acquire
      4.18%  pulseaudio  [kernel.kallsyms]           [k] lock_release
      2.78%  pulseaudio  [kernel.kallsyms]           [k] lock_acquire
      1.81%  pulseaudio  [kernel.kallsyms]           [k] __fget
      1.74%  pulseaudio  [kernel.kallsyms]           [k] do_sys_poll
      1.51%  pulseaudio  [kernel.kallsyms]           [k] mark_lock
      1.48%  pulseaudio  libasound.so.2.0.0          [.] 
softvol_convert_stereo_vol
      1.32%  pulseaudio  [kernel.kallsyms]           [k] 
trace_hardirqs_on_caller

I.e. the effect of the patch is very minor.

-- 
Alexander E. Patrakov


More information about the pulseaudio-discuss mailing list