Standard test needed to benchmark XRUNs

Optimize your system for ultimate performance.

Moderators: MattKingUSA, khz

tramp
Established Member
Posts: 2335
Joined: Mon Jul 01, 2013 8:13 am
Has thanked: 9 times
Been thanked: 454 times

Re: Standard test needed to benchmark XRUNs

Post by tramp »

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);
}
On the road again.
merlyn
Established Member
Posts: 1392
Joined: Thu Oct 11, 2018 4:13 pm
Has thanked: 168 times
Been thanked: 247 times

Re: Standard test needed to benchmark XRUNs

Post by merlyn »

Thanks tramp!
merlyn
Established Member
Posts: 1392
Joined: Thu Oct 11, 2018 4:13 pm
Has thanked: 168 times
Been thanked: 247 times

Re: Standard test needed to benchmark XRUNs

Post by merlyn »

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.
tramp
Established Member
Posts: 2335
Joined: Mon Jul 01, 2013 8:13 am
Has thanked: 9 times
Been thanked: 454 times

Re: Standard test needed to benchmark XRUNs

Post by tramp »

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.
On the road again.
User avatar
lilith
Established Member
Posts: 1698
Joined: Fri May 27, 2016 11:41 pm
Location: bLACK fOREST
Has thanked: 117 times
Been thanked: 57 times
Contact:

Re: Standard test needed to benchmark XRUNs

Post by lilith »

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.?
tramp
Established Member
Posts: 2335
Joined: Mon Jul 01, 2013 8:13 am
Has thanked: 9 times
Been thanked: 454 times

Re: Standard test needed to benchmark XRUNs

Post by tramp »

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)
On the road again.
User avatar
lilith
Established Member
Posts: 1698
Joined: Fri May 27, 2016 11:41 pm
Location: bLACK fOREST
Has thanked: 117 times
Been thanked: 57 times
Contact:

Re: Standard test needed to benchmark XRUNs

Post by lilith »

Thanks, I'll give it a try.
windowsrefund
Established Member
Posts: 64
Joined: Mon Jul 30, 2018 11:04 pm

Re: Standard test needed to benchmark XRUNs

Post by windowsrefund »

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.
tramp
Established Member
Posts: 2335
Joined: Mon Jul 01, 2013 8:13 am
Has thanked: 9 times
Been thanked: 454 times

Re: Standard test needed to benchmark XRUNs

Post by tramp »

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.
On the road again.
Drumfix
Established Member
Posts: 299
Joined: Mon Jan 26, 2009 5:15 pm
Been thanked: 11 times

Re: Standard test needed to benchmark XRUNs

Post by Drumfix »

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: 64
Joined: Mon Jul 30, 2018 11:04 pm

Re: Standard test needed to benchmark XRUNs

Post by windowsrefund »

About the suggestion to replace the nvidia card, what about video cards specifically, could lead to XRUNs?
tramp
Established Member
Posts: 2335
Joined: Mon Jul 01, 2013 8:13 am
Has thanked: 9 times
Been thanked: 454 times

Re: Standard test needed to benchmark XRUNs

Post by tramp »

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:
On the road again.
Drumfix
Established Member
Posts: 299
Joined: Mon Jan 26, 2009 5:15 pm
Been thanked: 11 times

Re: Standard test needed to benchmark XRUNs

Post by Drumfix »

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: 103
Joined: Fri Jan 29, 2010 2:24 pm
Location: Vilnius, Lithuania
Has thanked: 7 times
Been thanked: 3 times
Contact:

Re: Standard test needed to benchmark XRUNs

Post by eikakot »

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: 381
Joined: Sun May 28, 2017 3:52 pm

Re: Standard test needed to benchmark XRUNs

Post by Jack Winter »

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
Post Reply