LWN.net Logo

Bencina: Real-time audio programming 101: time waits for nothing

Ross Bencina has put up an introduction to glitch-free audio programming. "The main problems I'm concerned with here are with code that runs with unpredictable or un-bounded execution time. That is, you're unable to predict in advance how long a function or algorithm will take to complete. Perhaps this is because the algorithm you chose isn't appropriate, or perhaps it's because you don't understand the temporal behavior of the code you're calling. Whatever the cause, the result is the same: sooner or later your code will take longer than the buffer period and your audio will glitch."
(Log in to post comments)

Bencina: Real-time audio programming 101: time waits for nothing

Posted Jul 23, 2011 23:35 UTC (Sat) by simlo (subscriber, #10866) [Link]

This is a funny perspective on trying to do real-time programming on non-realtime OS'es - and even throwing in portability as an issue.

The truth is, that if you want to meet a 5 ms deadline with 100% certainty, non of his target OS'es are good enough. You need a real RTOS such as Linux with preempt-rt.

Bencina: Real-time audio programming 101: time waits for nothing

Posted Jul 24, 2011 9:36 UTC (Sun) by deepfire (subscriber, #26138) [Link]

The distinction between hard and soft real-time requirements isn't for nothing.

That said, what are the disadvantages of having a distribution run off a -RT kernel? Why isn't it more common?

Bencina: Real-time audio programming 101: time waits for nothing

Posted Jul 24, 2011 10:25 UTC (Sun) by dlang (✭ supporter ✭, #313) [Link]

a computer system makes a compromise between efficiency (throughput) and responsiveness (latency)

the most efficient system is a batch system where you submit your job and it runs them one (or at least one per core) at a time until the job finishes and then you get the results

the most responsive systems are the real time systems where the high priority processes can steal the system away from lower priority processes whenever they need it.

but just checking if there is a high priority process that wants the system eats a significant amount of resources.

so systems running the -rt kernel are slower than systems that run the regular kernel. they can be tuned to be more responsive (lower latency), but most people don't really need that.

to make an analogy here. If you have a job to transcribe audio tapes to typed documents, the most efficient way for you to work is to take one tape, work through it, take the next tape and do that one, etc (there can be efficiency in grouping similar tapes together, etc as well). this is a batch processing system (the way the initial computers were built)

a normal linux kernel would have you switch what tape you are working on every few minutes so that some work gets done on all projects (with you spending a bit more time on the higher priority tapes before you switch away from them)

a -rt kernel would have you check every few seconds to see if there is a higher priority tape that you should switch to working on. Also, if someone keeps feeding you high priority tapes, you will work on them exclusively and get absolutely no work done on the lower priority tapes

Bencina: Real-time audio programming 101: time waits for nothing

Posted Jul 24, 2011 10:40 UTC (Sun) by deepfire (subscriber, #26138) [Link]

dlang, first of all - thank you for a thorough overview of the tradeoff involved.

I think I was somewhat unclear in my inquiry (I'm aware of the latency vs. throughput conflict), as I was rather more interested in what are the /practical/ issues. The thing is -- I have (notably, uneducated) doubts as to whether the -RT efficiency loss constitutes something noticeable for an average user. Have there been any reviews/benchmarks published?

I think that, while synthetic benchmarks would certainly exhibit meaningful regressions -- how does that translate to actual desktop experience?

But that is not all. My more significant concern was about driver support -- does the -RT tree bring hardware support regressions?

Bencina: Real-time audio programming 101: time waits for nothing

Posted Jul 24, 2011 14:37 UTC (Sun) by joib (guest, #8541) [Link]

In the mainline kernel there is CONFIG_PREEMPT, which one might argue would be a better general-purpose choice than (the somewhat confusingly named) CONFIG_PREEMPT_VOLUNTARY; still almost all general-purpose distros use PREEMPT_VOLUNTARY since AFAIU there are problems with preemption and some drivers. Presumably, the same issues are certainly present also with PREEMPT_RT.

Performance.

Posted Jul 24, 2011 15:14 UTC (Sun) by gmatht (guest, #58961) [Link]

Well, there at least benchmarks in [1], some things are three times slower on average, others are basically unaffected. I suspect that if you have a machine that is primarily used for hard real time tasks, then it would be quite usable for a few normal desktop tasks. There are RT-Preempt kernels aimed at Debian [2].

[1] http://lwn.net/images/conf/rtlws11/papers/proc/p19.pdf
[2] http://www.ptxdist.org/software/linux-rt/debian_en.html

Bencina: Real-time audio programming 101: time waits for nothing

Posted Jul 24, 2011 16:24 UTC (Sun) by epa (subscriber, #39769) [Link]

the most efficient system is a batch system where you submit your job and it runs them one (or at least one per core) at a time until the job finishes and then you get the results
Not if your job performs I/O. Then it can still be more efficient to have several jobs running so that while one is blocked on I/O, another can make progress. I believe this was the original motivation for inventing multitasking operating systems.

Bencina: Real-time audio programming 101: time waits for nothing

Posted Jul 24, 2011 17:16 UTC (Sun) by jch (guest, #51929) [Link]

> the most efficient system is a batch system where you submit your job and it runs them one (or at least one per core) at a time

Not necessarily, since a multitasking system can overlap I/O with CPU activity. Some claim that was the reason why multitasking was invented in the first place.

-- jch

Bencina: Real-time audio programming 101: time waits for nothing

Posted Jul 25, 2011 17:58 UTC (Mon) by macc (subscriber, #510) [Link]

That is actually a bit off.

You have IO and other delays to consider.

So you start a number of jobs that keep CPU and IO busy in a balanced way.
While one job is idle, waiting for IO to complete, another task
can load the cpu.

The issue with RT stuff is that the more competing RT tasks you have
the less likely it becomes that all requirements are met.

And proving that all RT requirements are met is a very deep task.

My reason for using an RT addon that runs the linux system as the
least urgent task. And do as few RT requirements as possible.

Bencina: Real-time audio programming 101: time waits for nothing

Posted Jul 25, 2011 16:11 UTC (Mon) by aaron (subscriber, #282) [Link]

The article is a very good introduction to the sorts of priority and locking issues you have to deal with when learning to code for low-latency and RT.

A hard-RT OS won't help with the issues he discusses.

It's a very good article, you should read it. :)

Bencina: Real-time audio programming 101: time waits for nothing

Posted Jul 26, 2011 21:15 UTC (Tue) by simlo (subscriber, #10866) [Link]

Well, some of his issues is that you can't use muteces, nor "trust the scheduler". On a hard-RT OS you can. Unfortunately, people remember these things in the back of the head, but not the why, when they go to hard-RT and make crappy designs.

That said, there are still a lot of API calls you must avoid and a allocating memory is dodgy.

Bencina: Real-time audio programming 101: time waits for nothing

Posted Jul 27, 2011 4:27 UTC (Wed) by mikov (subscriber, #33179) [Link]

Correct me if I am wrong, but it seems things are somewhat better than the naive reading of the linked article would imply.

I am pretty sure priority inheritance is available in Linux in ordinary kernels (not only RT-preempt), and has been available in Win32 for ever.

So, there is no good reason to avoid locking as long as it is not done indiscriminately. Obviously you don't want to use a lock while reading a file, but a priority inheritance lock around updating queue pointers is perfectly fine in this day and age, when we are talking about millisecond latencies.

In fact it is easy to achieve a similar effect manually by assigning a fixed maximum priority to every lock, not to mention PTHREAD_PRIO_PROTECT. So, I am afraid a large part of the article is not entirely convincing.

Off-topic: Does Win32 have priority inheritance?

Posted Jul 28, 2011 14:42 UTC (Thu) by simlo (subscriber, #10866) [Link]

I could not find any documentation on the web, only someone asking why it was in win95/98 but removed in winNT and on.

Do you have a link?

Bencina: Real-time audio programming 101: time waits for nothing

Posted Aug 7, 2011 10:21 UTC (Sun) by Tov (guest, #61080) [Link]

The author of the article is more experienced in RT programming, than you give him credit for.

Priority inheriting locks may be available in several OS's, but it does not change the fact that locking in time critical code is wrong! When you try to acquire a lock your code may block until the other lock holders release the lock. This means that you incur at least two task switches and relinquish control to other code paths, which worst case execution time will add to the worst case latency. This is all nicely described in the article. Priority inheriting locks may be useful for avoiding certain types of deadlock problems, but they do not change the basic rule that:

"Do not acquire locks or mutexes in time critical code!"

Instead lockless techniques like atomics, flags, dual counters, queues, ring buffers etc. should be used for communicating between the RT tasks and the non-RT tasks.

Copyright © 2011, Eklektix, Inc.
Comments and public postings are copyrighted by their creators.
Linux is a registered trademark of Linus Torvalds