Page 2 of 10

Re: Standard test needed to benchmark XRUNs

Posted: Mon Dec 24, 2018 11:00 am
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);
}

Re: Standard test needed to benchmark XRUNs

Posted: Mon Dec 24, 2018 11:29 am
by merlyn
Thanks tramp!

Re: Standard test needed to benchmark XRUNs

Posted: Mon Dec 24, 2018 6:08 pm
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.

Re: Standard test needed to benchmark XRUNs

Posted: Tue Dec 25, 2018 5:55 pm
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.

Re: Standard test needed to benchmark XRUNs

Posted: Tue Dec 25, 2018 5:59 pm
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.?

Re: Standard test needed to benchmark XRUNs

Posted: Tue Dec 25, 2018 6:27 pm
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)

Re: Standard test needed to benchmark XRUNs

Posted: Tue Dec 25, 2018 6:32 pm
by lilith
Thanks, I'll give it a try.

Re: Standard test needed to benchmark XRUNs

Posted: Thu Dec 27, 2018 4:14 am
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.

Re: Standard test needed to benchmark XRUNs

Posted: Thu Dec 27, 2018 6:34 am
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.

Re: Standard test needed to benchmark XRUNs

Posted: Thu Dec 27, 2018 8:51 am
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

Re: Standard test needed to benchmark XRUNs

Posted: Thu Dec 27, 2018 3:58 pm
by windowsrefund
About the suggestion to replace the nvidia card, what about video cards specifically, could lead to XRUNs?

Re: Standard test needed to benchmark XRUNs

Posted: Thu Dec 27, 2018 5:55 pm
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:

Re: Standard test needed to benchmark XRUNs

Posted: Thu Dec 27, 2018 6:29 pm
by Drumfix
There is no need to run for a new graphics card unless you assured it really is the culprit.

Re: Standard test needed to benchmark XRUNs

Posted: Thu Dec 27, 2018 7:23 pm
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

Re: Standard test needed to benchmark XRUNs

Posted: Thu Dec 27, 2018 9:49 pm
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.