Standard test needed to benchmark XRUNs

Optimize your system for ultimate performance.

Moderators: MattKingUSA, khz

User avatar
tramp
Established Member
Posts: 1313
Joined: Mon Jul 01, 2013 8:13 am

Re: Standard test needed to benchmark XRUNs

Postby tramp » Mon Dec 24, 2018 11:00 am

merlyn wrote:I found an xrun counter that tramp wrote on this thread


Yes, that could easily extended to a stress test.
Here I've add a growing atan function as dsp load blob, so DSP load will grow with every circle the tests runs.
It will detect then at which DSP load the first Xrun happen, and will stop the test at 95% DSP load.
At least it will show us how many circles needed to reach 95% DSP load, and at which DSP load the first Xrun happen.
So, for example here is the output I get with 48kHz 128/2 frames/buffer:

Samplerate 48000
Buffersize is 128
jack running with realtime priority
in complete 304 Xruns in 9054 circles
first Xrun happen at DSP load 60.719921 circle 7022


and here is with 48kHz at 256/2 frames/buffer
Samplerate 48000
Buffersize is 256
jack running with realtime priority
in complete 25 Xruns in 19352 circles
first Xrun happen at DSP load 75.472885 circle 16863


and here it is with 512/2 frames/buffer
Samplerate 48000
Buffersize is 512
jack running with realtime priority
in complete 8 Xruns in 38076 circles
first Xrun happen at DSP load 81.324150 circle 36127


all this with pulseaudio running.

Code: Select all

#include <stdio.h>
#include <errno.h>
#include <unistd.h>
#include <signal.h>
#include <stdlib.h>
#include <math.h>

#include <jack/jack.h>

/*   gcc -Wall xruncounter.c -lm `pkg-config --cflags --libs jack` -o xruncounter */

jack_client_t *client;
jack_port_t *in_port;
jack_port_t *out_port;

static int xruns = 0;
static int grow = 1;
static int first_x_run = 0;
static float dsp_load = 0;
static int run = 1;


void
jack_shutdown (void *arg)
{
   exit (1);
}

int
jack_xrun_callback(void *arg)
{
   /* count xruns */
   xruns += 1;
   if (xruns == 1) {
       first_x_run = grow/100;
       dsp_load = jack_cpu_load(client);
   }
   fprintf (stderr, "Xrun %i at DSP load %f\n",xruns , jack_cpu_load(client));
   if ((int)jack_cpu_load(client)>95) run = 0;
   return 0;
}

int
jack_srate_callback(jack_nframes_t samplerate, void* arg)
{
    fprintf (stderr, "Samplerate %i \n", samplerate);
    return 0;
}

int
jack_buffersize_callback(jack_nframes_t nframes, void* arg)
{
    fprintf (stderr, "Buffersize is %i \n", nframes);
    return 0;
}

int
jack_process(jack_nframes_t nframes, void *arg)
{
    double d = 0;
    for (int j ; j < grow; ++j) {
        d = tan(atan(tan(atan(tan(atan(tan(atan(tan(atan(123456789.123456789))))))))));
    }
    grow +=100;
    d = 0;
    return (int)d;
}

void
signal_handler (int sig)
{
   jack_client_close (client);
   fprintf (stderr, " signal %i received, exiting ...\n", sig);
   exit (0);
}

int
main (int argc, char *argv[])

{

   if ((client = jack_client_open ("xruncounter", JackNullOption, NULL)) == 0) {
      fprintf (stderr, "jack server not running?\n");
      return 1;
   }

   in_port = jack_port_register(
     client, "in_0", JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0);
   out_port = jack_port_register(
        client, "out_0", JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0);

   signal (SIGQUIT, signal_handler);
   signal (SIGTERM, signal_handler);
   signal (SIGHUP, signal_handler);
   signal (SIGINT, signal_handler);

   jack_set_xrun_callback(client, jack_xrun_callback, 0);
   jack_set_sample_rate_callback(client, jack_srate_callback, 0);
   jack_set_buffer_size_callback(client, jack_buffersize_callback, 0);
   jack_set_process_callback(client, jack_process, 0);
   jack_on_shutdown (client, jack_shutdown, 0);

   if (jack_activate (client)) {
      fprintf (stderr, "cannot activate client");
      return 1;
   }
   
   if (!jack_is_realtime(client)) {
       fprintf (stderr, "jack isn't running with realtime priority\n");
   } else {
      fprintf (stderr, "jack running with realtime priority\n");
   }
   
   while (run) {
      usleep (100000);
      fprintf (stderr, "DSP load %f  \r", jack_cpu_load(client));
   }
   
   fprintf(stderr, "in complete %i Xruns in %i circles\nfirst Xrun happen at DSP load %f circle %i\n", xruns, grow/100, dsp_load, first_x_run);

   jack_client_close (client);
   exit (0);
}

merlyn
Established Member
Posts: 172
Joined: Thu Oct 11, 2018 4:13 pm

Re: Standard test needed to benchmark XRUNs

Postby merlyn » Mon Dec 24, 2018 11:29 am

Thanks tramp!

merlyn
Established Member
Posts: 172
Joined: Thu Oct 11, 2018 4:13 pm

Re: Standard test needed to benchmark XRUNs

Postby merlyn » Mon Dec 24, 2018 6:08 pm

I've tried it and have some results. This is great, thanks again.
Samplerate 48000
Buffersize is 16
jack running with realtime priority
Xrun 1 at DSP load 97.712875
Xrun 2 at DSP load 97.712875
Xrun 3 at DSP load 97.712875
Xrun 4 at DSP load 98.856438
Xrun 5 at DSP load 51.980774
Xrun 6 at DSP load 28.242638
Xrun 7 at DSP load 28.242638
Xrun 8 at DSP load 16.373569
in complete 8 Xruns in 1502 circles
first Xrun happen at DSP load 97.712875 circle 1381

Samplerate 48000
Buffersize is 32
jack running with realtime priority
Xrun 1 at DSP load 99.322708
Xrun 2 at DSP load 99.661354
Xrun 3 at DSP load 99.661354
Xrun 4 at DSP load 99.661354
Xrun 5 at DSP load 99.830673
Xrun 6 at DSP load 99.830673
in complete 6 Xruns in 2404 circles
first Xrun happen at DSP load 99.322708 circle 2317

Samplerate 48000
Buffersize is 64
jack running with realtime priority
Xrun 1 at DSP load 99.635452
Xrun 2 at DSP load 99.635452
Xrun 3 at DSP load 99.635452
in complete 3 Xruns in 4505 circles
first Xrun happen at DSP load 99.635452 circle 4472

Samplerate 48000
Buffersize is 128
jack running with realtime priority
Xrun 1 at DSP load 99.989548
Xrun 2 at DSP load 99.989548
Xrun 3 at DSP load 99.989548
in complete 3 Xruns in 8935 circles
first Xrun happen at DSP load 99.989548 circle 8926

This was without pulseaudio running.

User avatar
tramp
Established Member
Posts: 1313
Joined: Mon Jul 01, 2013 8:13 am

Re: Standard test needed to benchmark XRUNs

Postby tramp » Tue Dec 25, 2018 5:55 pm

merlyn wrote:first Xrun happen at DSP load 99.989548 circle 8926


This looks like a very well configured system with a good sound-card.

tramp wrote:first Xrun happen at DSP load 60.719921 circle 7022


This is with a internal HDA-Intel ALC891, and I suspect the sound-card to use the remaining time.
I've added a time measurement for frame and processing time, and found that the process use ~1.81ms, while the jack-frame use ~3.66ms during the first Xrun, means we've 1.85ms left. The DA converter of the HDA-Intel is to be expected as the bottleneck here, oh, not really a surprise. :lol:
Truly time measurement in this fraction have to be taken with a grain of salt, as any value could be already the value from the next frame, but, it's enough to paint a picture.

User avatar
lilith
Established Member
Posts: 730
Joined: Fri May 27, 2016 11:41 pm
Location: bLACK fOREST
Contact:

Re: Standard test needed to benchmark XRUNs

Postby lilith » Tue Dec 25, 2018 5:59 pm

tramp wrote:
merlyn wrote:I found an xrun counter that tramp wrote on this thread


Yes, that could easily extended to a stress test.
Here I've add a growing atan function as dsp load blob, so DSP load will grow with every circle the tests runs.
It will detect then at which DSP load the first Xrun happen, and will stop the test at 95% DSP load.
At least it will show us how many circles needed to reach 95% DSP load, and at which DSP load the first Xrun happen.
So, for example here is the output I get with 48kHz 128/2 frames/buffer:

Samplerate 48000
Buffersize is 128
jack running with realtime priority
in complete 304 Xruns in 9054 circles
first Xrun happen at DSP load 60.719921 circle 7022


and here is with 48kHz at 256/2 frames/buffer
Samplerate 48000
Buffersize is 256
jack running with realtime priority
in complete 25 Xruns in 19352 circles
first Xrun happen at DSP load 75.472885 circle 16863


and here it is with 512/2 frames/buffer
Samplerate 48000
Buffersize is 512
jack running with realtime priority
in complete 8 Xruns in 38076 circles
first Xrun happen at DSP load 81.324150 circle 36127


all this with pulseaudio running.

Code: Select all

#include <stdio.h>
#include <errno.h>
#include <unistd.h>
#include <signal.h>
#include <stdlib.h>
#include <math.h>

#include <jack/jack.h>

/*   gcc -Wall xruncounter.c -lm `pkg-config --cflags --libs jack` -o xruncounter */

jack_client_t *client;
jack_port_t *in_port;
jack_port_t *out_port;

static int xruns = 0;
static int grow = 1;
static int first_x_run = 0;
static float dsp_load = 0;
static int run = 1;


void
jack_shutdown (void *arg)
{
   exit (1);
}

int
jack_xrun_callback(void *arg)
{
   /* count xruns */
   xruns += 1;
   if (xruns == 1) {
       first_x_run = grow/100;
       dsp_load = jack_cpu_load(client);
   }
   fprintf (stderr, "Xrun %i at DSP load %f\n",xruns , jack_cpu_load(client));
   if ((int)jack_cpu_load(client)>95) run = 0;
   return 0;
}

int
jack_srate_callback(jack_nframes_t samplerate, void* arg)
{
    fprintf (stderr, "Samplerate %i \n", samplerate);
    return 0;
}

int
jack_buffersize_callback(jack_nframes_t nframes, void* arg)
{
    fprintf (stderr, "Buffersize is %i \n", nframes);
    return 0;
}

int
jack_process(jack_nframes_t nframes, void *arg)
{
    double d = 0;
    for (int j ; j < grow; ++j) {
        d = tan(atan(tan(atan(tan(atan(tan(atan(tan(atan(123456789.123456789))))))))));
    }
    grow +=100;
    d = 0;
    return (int)d;
}

void
signal_handler (int sig)
{
   jack_client_close (client);
   fprintf (stderr, " signal %i received, exiting ...\n", sig);
   exit (0);
}

int
main (int argc, char *argv[])

{

   if ((client = jack_client_open ("xruncounter", JackNullOption, NULL)) == 0) {
      fprintf (stderr, "jack server not running?\n");
      return 1;
   }

   in_port = jack_port_register(
     client, "in_0", JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0);
   out_port = jack_port_register(
        client, "out_0", JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0);

   signal (SIGQUIT, signal_handler);
   signal (SIGTERM, signal_handler);
   signal (SIGHUP, signal_handler);
   signal (SIGINT, signal_handler);

   jack_set_xrun_callback(client, jack_xrun_callback, 0);
   jack_set_sample_rate_callback(client, jack_srate_callback, 0);
   jack_set_buffer_size_callback(client, jack_buffersize_callback, 0);
   jack_set_process_callback(client, jack_process, 0);
   jack_on_shutdown (client, jack_shutdown, 0);

   if (jack_activate (client)) {
      fprintf (stderr, "cannot activate client");
      return 1;
   }
   
   if (!jack_is_realtime(client)) {
       fprintf (stderr, "jack isn't running with realtime priority\n");
   } else {
      fprintf (stderr, "jack running with realtime priority\n");
   }
   
   while (run) {
      usleep (100000);
      fprintf (stderr, "DSP load %f  \r", jack_cpu_load(client));
   }
   
   fprintf(stderr, "in complete %i Xruns in %i circles\nfirst Xrun happen at DSP load %f circle %i\n", xruns, grow/100, dsp_load, first_x_run);

   jack_client_close (client);
   exit (0);
}


How can this script be executed? Does Jack need to run, etc., etc.?
https://soundcloud.com/lilith_93
_____________________________
Debian 9 (XFCE) & KXStudio repos

User avatar
tramp
Established Member
Posts: 1313
Joined: Mon Jul 01, 2013 8:13 am

Re: Standard test needed to benchmark XRUNs

Postby tramp » Tue Dec 25, 2018 6:27 pm

lilith wrote:How can this script be executed? Does Jack need to run, etc., etc.?


It's a program, after copy and save it as xruncounter.c, you need to compile it with the command given on top of it:

Code: Select all

gcc -Wall xruncounter.c -lm `pkg-config --cflags --libs jack` -o xruncounter

you could copy and past the command into your terminal. All you need to build it are the jack development package, libjack-dev (or libjack-jackd2-dev when you use jackd2, which is more expected).
Then you could execute it with
./xruncounter
Yes, jack needs to be running. (even if the prog will start jack if it isn't running, it's much better to have jack running before start the test)

User avatar
lilith
Established Member
Posts: 730
Joined: Fri May 27, 2016 11:41 pm
Location: bLACK fOREST
Contact:

Re: Standard test needed to benchmark XRUNs

Postby lilith » Tue Dec 25, 2018 6:32 pm

Thanks, I'll give it a try.
https://soundcloud.com/lilith_93
_____________________________
Debian 9 (XFCE) & KXStudio repos

windowsrefund
Established Member
Posts: 63
Joined: Mon Jul 30, 2018 11:04 pm

Re: Standard test needed to benchmark XRUNs

Postby windowsrefund » Thu Dec 27, 2018 4:14 am

Just wanted to share my results and a bit about my box

OS: Ubuntu 18.10
CPU: Intel i3-8100 (4 cores) @3.60GHz
Video: NVIDIA GF119 GeForce GT 610
Sound: Intel HDA ALC887

PulseAudio is running.

Code: Select all

Samplerate 48000
Buffersize is 256
jack running with realtime priority
first Xrun happen at DSP load 70.060760 circle 17497


Given the above, I'd be really interested in opinions in terms of what I might tweak (software) or upgrade (hardware) to improve performance?

Many thanks.

User avatar
tramp
Established Member
Posts: 1313
Joined: Mon Jul 01, 2013 8:13 am

Re: Standard test needed to benchmark XRUNs

Postby tramp » Thu Dec 27, 2018 6:34 am

windowsrefund wrote:Given the above, I'd be really interested in opinions in terms of what I might tweak (software) or upgrade (hardware) to improve performance?


Your results been similar to mine with a Intel HDA chipset.
I don't believe that we could expect a better performance from this chipset.
To improve performance a dedicated Sound-card is needed.

Drumfix
Established Member
Posts: 208
Joined: Mon Jan 26, 2009 5:15 pm

Re: Standard test needed to benchmark XRUNs

Postby Drumfix » Thu Dec 27, 2018 8:51 am

The HDA is fine. The problem is most likely the nvidia graphics card.

Here are the results with my system:

AMD Athlon II X4 620
Onboard AMD graphic
HDA with ALC889

Code: Select all

Samplerate 48000
Buffersize is 128
jack running with realtime priority
Xrun 1 at DSP load 98.455978
...
in complete 4 Xruns in 8148 circles

windowsrefund
Established Member
Posts: 63
Joined: Mon Jul 30, 2018 11:04 pm

Re: Standard test needed to benchmark XRUNs

Postby windowsrefund » Thu Dec 27, 2018 3:58 pm

About the suggestion to replace the nvidia card, what about video cards specifically, could lead to XRUNs?

User avatar
tramp
Established Member
Posts: 1313
Joined: Mon Jul 01, 2013 8:13 am

Re: Standard test needed to benchmark XRUNs

Postby tramp » Thu Dec 27, 2018 5:55 pm

Drumfix wrote:The HDA is fine. The problem is most likely the nvidia graphics card.


Good point, I'll retry with the internal Intel chip.

windowsrefund wrote:About the suggestion to replace the nvidia card, what about video cards specifically, could lead to XRUNs?


Nvidia cards will rescheduling interrupts, therewith disturb the performance. (Still I use one myself) :oops:

Drumfix
Established Member
Posts: 208
Joined: Mon Jan 26, 2009 5:15 pm

Re: Standard test needed to benchmark XRUNs

Postby Drumfix » Thu Dec 27, 2018 6:29 pm

There is no need to run for a new graphics card unless you assured it really is the culprit.

User avatar
eikakot
Established Member
Posts: 81
Joined: Fri Jan 29, 2010 2:24 pm
Location: Vilnius, Lithuania
Contact:

Re: Standard test needed to benchmark XRUNs

Postby eikakot » Thu Dec 27, 2018 7:23 pm

Just like "nvidia" cards, Wifi/Bluetooth cards tend to do the same with interrupts sometimes. With nvidia proprietary driver I remember it used to be it's frequency scheduler that was disturbing the rt performance. So I used to turn in off while starting jack with something similar like this:

Code: Select all

nvidia-settings -a [gpu:0]/GPUPowerMizerMode=1

Jack Winter
Established Member
Posts: 323
Joined: Sun May 28, 2017 3:52 pm

Re: Standard test needed to benchmark XRUNs

Postby Jack Winter » Thu Dec 27, 2018 9:49 pm

The nvidia driver is also likely to cause spikes in the kernel scheduling latency, ie threads scheduled to run might start later than when using the intel driver. Not sure that is the case for this test, but might influence the results.
Reaper/KDE/Archlinux. i7-2600k/16GB + i7-4700HQ/16GB, RME Multiface/Babyface, Behringer X32, WA273-EQ, 2 x WA-412, ADL-600, Tegeler TRC, etc 8) For REAPER on Linux information: https://wiki.cockos.com/wiki/index.php/REAPER_for_Linux


Return to “System Tuning and Configuration”

Who is online

Users browsing this forum: No registered users and 1 guest