Menu

#60 Excess CPU usage in cdemu-daemon

open
None
cdemu-daemon
default
2013-03-19
2013-03-07
No

In http://inai.de/test/ you will find a sil.cue and sil.wav.xz (decompress this). Load the CUE file. When playing back the audio using mplayer cdda://1, the CPU usage of cdemu-daemon-2.0.0 goes to maximum for me. Can you reproduce this? Why would this happen?

Discussion

  • Rok Mandeljc

    Rok Mandeljc - 2013-03-07

    Yeah, I can reproduce this using git HEAD as well. For me, the CPU spike already occurs on loading (without running mplayer at all); I'll check what's going on.

     
  • Rok Mandeljc

    Rok Mandeljc - 2013-03-07

    At the first glance, I'd say the culprit is inefficient buffering in the sndfile filter. Can you try increasing the buffer length? In filter-snd-file-filter.c, around line 145, change:
    self->priv->buflen = self->priv->format.channels * sizeof(guint16);
    to:
    self->priv->buflen = self->priv->format.channels * sizeof(guint16) * 588;

    And around line 177, change:
    read_length = sf_readf_short(self->priv->sndfile, (short )self->priv->buffer, 1);
    to:
    read_length = sf_readf_short(self->priv->sndfile, (short
    )self->priv->buffer, 588);

    This should read and cache 588 frames, an equivalent of a whole sector. I think the rest of the code should handle increased buffer without any modifications; maybe it only needs an additional testing for chunks at the end of sound stream, but even that shouldn't be an issue with valid cd-rom track files.

    I'll be away for the next couple of days, and will finish fixing this once I get back.

     
  • Rok Mandeljc

    Rok Mandeljc - 2013-03-07

    Ah, also, in the seek before read, 'frame' needs to be multiplied by 588 to read from the correct offset.

     
  • Rok Mandeljc

    Rok Mandeljc - 2013-03-11

    OK, I've committed the patch that increases buffer to 588 samples (2352 bytes), and it seems to fix the issue for me. Please test if you can. Thanks!

     
  • Jan Engelhardt

    Jan Engelhardt - 2013-03-13

    Seems to work for me as well.

     
  • Jan Engelhardt

    Jan Engelhardt - 2013-03-16

    The problem seems to be only fixed for WAV. When loading a CUE file that references, for example, a FLAC file,

    FILE "dubdubdub.flac" WAVE

    then there is high CPU usage again.

     
  • Rok Mandeljc

    Rok Mandeljc - 2013-03-16

    Hmmm, odd. FLAC and WAV are both handled by libsndfile, so there should not be any differences.

    When playing a FLAC/CUE I do not get high CPU usage, but I did get some stuttering (along with "Audio device got stuck!" messages in mplayer). Increasing the buffer to accomodate 32 sectors seems to fix that issue, too.

     
  • Jan Engelhardt

    Jan Engelhardt - 2013-03-17

    I have a theory that it is specific to the audio data stored in the particular FLAC file that is before me. It is a multi-track CD, i.e. there are a few seconds of silence between two tracks. mplayer, too, shows a momentarily rise in CPU power consumption by factor 2× when the new track begins in the middle of the FLAC file. I believe this may be due to the presence of a "key frame" (as it would be called in the video world) in the FLAC audio stream. I will send you the URLs in private.

     
  • Henrik Stokseth

    Henrik Stokseth - 2013-03-17

    Won't the block layer use "readahead" caching? It should kick in after a seek followed by a read. On physical hardware that uses busmastering you shouldn't notice a CPU spike, however it may very well account for at least some of the CPU usage here... decompression only adds to it.

    Is there any chance we could be a bit smarter about how we do caching? For instance turn off readahead whenever decompression is involved?

     
    • Rok Mandeljc

      Rok Mandeljc - 2013-03-18

      Since this is audio cd, block layer and its readahead caching do not come into play.

      The issue is that decoding is for some reason very expensive in the pregap/silence region of the FLAC file in question. So the smaller our cache buffer in the sndfile filter, to more seeking and decoding we have to do in that region, resulting in increased CPU use.

      I am not familiar with structure of FLAC stream, but if it has key frames, then there might be only one key frame in that region, meaning that all seeks are done to there, and then stream is (incrementally) decoded up to desired frame.

       
  • Jan Engelhardt

    Jan Engelhardt - 2013-03-18

    I do not think that the kernel block layer (and thus, readahead) comes to use, because DAE is done using ioctls on /dev/sr0 rather than read(2)ing from the block device.

     

Log in to post a comment.