[fixed RNS 3.5.4] Bad performance (xruns) in 3.5 with Jack

Hello. Are you sure you have pipewire disabled? For me the stability problems stopped when I uninstalled pipewire from my debian system - it seems that pipewire itself has a jack interface, and it may be renoise and/or qjack will use it when it is configured by standard, which might be the case.

But interesting still, that this only happens for the new updates since the audio engine has been reworked. Maybe some parameters are botched somewhere, so a standard system mixer is selected instead of direct sound card access?

Hello @OopsIFly,

You are right that pipewire was in fact installed, without my knowledge. So I went ahead and removed it. Unfortunately this didn’t have any effect on the problem.

Just to be sure, I reinstalled it again and used lsof to query if Renoise uses that library, but it seems that Renoise does not access it, at least not on this system.

After a lot more investigation into this, I have gained a much better understanding of what causes this bug. The good news is that it’s quite easy to work around, now that I know what causes it.

Technical explanation of the issue

The complicating factor, which I realized only after uncovering the cause, is that there are actually two completely independent Renoise bugs that both have the same effect. And both were triggering on my system. They are:

  1. The thread priorities are hardcoded to 99, which is not allowed on many systems (Jackd packages on Debian and derivatives ship with 95 as the maximum). Hence the system call fails altogether and the thread stays at low priority. This can be seen in the console log as:

    Renoise LOG> System: Changing a threads priority to '99' FAILED (error: 1)!
    
  2. Thread priorities of the audio threads are not set correctly when Renoise starts, only when you actively switch the number of threads using the ā€œOptions → Multi Coreā€ submenu.

Note that when using only one core, no helper threads are created, and Jack’s main thread is used instead, which is already correctly prioritized. So the problem does not occur in that scenario, only when 2 or more cores are used.

Workarounds

Let me present the easy workarounds first:

  1. The easiest way is to simply increase the limit. On Debian and derivates, this can be done by opening the file /etc/security/limits.d/audio.conf, and increasing the number on the rtprio line to 99. Then reboot.

  2. This is easy, just switch from the number of cores that you want to use, to a different number, and then back. Unfortunately this needs to be done every time Renoise is started.

Advanced workaround

Luckily, the Renoise developers have named their threads, so they’re actually identifiable from the outside. A slightly more advanced workaround is therefore to set the priority yourself, using a script. This has the advantage that it can be automated, and you don’t need to do the ā€œOptions → Multi Coreā€ trick every time you start Renoise. It also means that you can set the priority to something else than 99, if you are uncomfortable raising the limit (which does have some very minor security implications). Priority 99 is not actually needed for smooth playback, using whatever Jackd is using is more than good enough.

To set the thread priorities, add a script which contains the following:

#!/bin/bash

renoise &
pid=$!
sleep 10
ps -eL -o tid,comm | grep "Audio Slave" | awk '{print $1}' | xargs -n1 -r chrt -f --pid 95
wait $pid

Then use that to start Renoise instead of the binary itself.

The sleep 10 can be increased if your Renoise instance takes a long time to start, for example because of many plugins. 95 can also be changed if you want a different priority.

Resolution

You can check that the threads are correctly prioritized with this command:

ps -eL -o priority,comm | grep "Audio Slave"

That will list each thread. If the number in the first column is negative or ā€œrtā€, they are correctly prioritized.

Once the workarounds are in place, Renoise 3.5 in fact performs better than 3.4, so kudos to the developers for that!

Getting the bugs fixed in Renoise

I’m going to create new threads for each of these bugs, since my new description of the problem should be much easier to grasp for the developers, and what I originally posted is not that relevant anymore. Plus, this thread is getting pretty long by now.

2 Likes

New bug reports:

1 Like

After implementing that workaround and running the above tests, it appears that xrun does not occur even when quantum is reduced to 48.
This does indeed seem to offer better performance than V3.4.4.

@Kristian_Amlie
You did a great job finding that workaround. I think it makes for a beautiful bug report too.

However, when I load a new project in Renoise, the priority of that process seems to revert back to its original state.
It might be better to run the command periodically as shown below.

#!/bin/bash

renoise &

while ps -C renoise > /dev/null ; do
    ps -eL -o tid,comm | grep "Audio Slave" | awk '{print $1}' | xargs -n1 -r chrt -f --pid 95
    sleep 5
done

@Mumdad
This will likely be helpful information for you and other general Linux users.

1 Like

After further consideration of the workaround, this seems sufficient on its own.
Sorry if I’m wrong.

#/bin/bash

chrt --fifo 98 renoise

@tkna: Good point about the resetting of priorities when loading a new song!

Careful with that last command though. This will set all of the Renoise threads to high priority, many of which should not have it. Those that should be low priority (such as the GUI thread) may interfere with smooth playback.

I see. In that case, I’ll proceed with this method until the relevant part of Renoise is updated.

#!/bin/bash

renoise &

while ps -C renoise > /dev/null ; do
    ps -eL -o tid,comm | grep "Audio Slave" | awk '{print $1}' | xargs -n1 -r chrt --fifo --pid 98
    sleep 5
done
1 Like

Lol, and I had already seen the new Renoise 3.5 working with 48/2 in server synchronous mode (2ms latency @ 48khz), with realtime kernel and all tweaks like setting /dev/cpu_dma_latency to zero keeping the file open (i.e. cyclictest does that, if you want an easy fix, run that tool from linux rt tools and keep it running while working…take care, it will disable cpu clocking and run at full freq full time on most systems, ensure cooling for laptops…)…Then wondering why it was still a little unstable under load, it still had x-runs at times…but did not test much, was just glad Renoise could now work under 5ms without stuttering right away…

This bug is hideous, and I wonder why I had missed it, when I even had seen already the processes priorites when tuning the interrupts, I missed it… Didn’t use renoise enough in the mean time…

Also, changing number of cpus renoise will set it’s audio slave threads at realtime priority ā€œ65ā€ when using jack, just 5 steps under jackdbus which sets itself at priority 70. This makes sense, considering you may use other jack apps, and that you could set the midi/input/sound card/usb interrupt to priorities even above to make sure everything is in place. So the scripts setting the worker threads to 98 maybe mess up this a little. I remember, some point before 3.5 the worker threads seemed always at very high priorities, no matter of alsa or jack, and this was probably suboptimal for jack performance…

Should it be 5 lower than jackdbus?
Something like this?

#!/bin/bash

renoise &

prio=$(echo $(ps -eL -o priority,comm | grep jackdbus | grep "^-" | sed -e 's@^-@@' -e 's@ .*$@@')-6 | bc)

while ps -C renoise > /dev/null ; do
    ps -eL -o tid,comm | grep "Audio Slave" | awk '{print $1}' | xargs -n1 -r chrt --fifo --pid $prio
    sleep 5
done

Have not tested your script, but setting the jack priority from 70 to 75 also made Renoise create the Audio Slave threads at a priority of 70 instead of 65, when I reset the number of used cores. So I guess 5 points lower than the jack thread is what is intended by the Renoise devs…