views:

465

answers:

3

Some background

I'm working on building a programming language for digital media programming, which should support concurrency using no-sharing message passing and soft real-time (i.e. do your best to compute audio/video without losing samples or frames and with a constant throughput).

It turns out that both these features are surprisingly difficult to combine, mainly because of one particular constraint: real-time code should not dynamically allocate memory.

My language should make it easy to implement something like this:

  • One thread computes audio samples based on parameters. These can be, for example, the values of different controls of a synthesizers. This thread runs "in real time".
  • One thread receives input from the user or from another computer to change those values. This could be the GUI thread, for instance, reacting to the user turning in a knob with the mouse.

I want the new values set by the user to be sent through a queue to the synthesizer engine. Now the problem would not be interesting if I only wanted to send floats and other atomic values. Actually, I want any kind of data to be able to flow from one thread to another, even a complex object or a data structure, and this should be possible for any configuration of threads and priorities. Without dynamic memory allocation on the real-time side, this becomes very difficult without imposing what seems like arbitrary restrictions on the programmer.

Erlang is often advertized as a good fit for real-time systems. My understanding is that Erlang does never, however, disallow memory allocation. If I did the same, it would make lots of problems go away, at the cost of introducing non-deterministic timing in the code that performs those allocation.

The question

So what makes Erlang such a good fit? Does it implement special tricks to circumvent the problems induced by memory allocation, or does it ignore the problem entirely? Does it take another approach to real-time?

An example to illustrate the question

Let's assume that we're writing a synthesizer in Erlang, which has to produce 64 samples every 50 milliseconds, otherwise there's cracks and pops in the sound. Let's assume also that when I move some slider around on the string, a small object (let's say it's a list or a tuple containing the parameter's name and new value) has to be sent out from the GUI process to the audio process, where a copy is created. This would requrie dynamic memory allocation. How would Erlang help me make sure that this allocation does not delay my audio computation?

+2  A: 

Since Erlang was created by Ericcson Communications for use in telecommunication, fast and scalable is an important consideration.

You may want to look at this article regarding trying to get Erlang ready for hard real-time applications, to see what problems they need to overcome for that. http://lambda-the-ultimate.org/node/2954

You may find that some of the issues that are still there may be a show-stopper for your application also.

You may also find this of interest, as FP will be different than OOP, so some of the problems you encounter in OOP will be different in the FP domain. http://blog.ribomation.com/2009/06/28/the-ups-and-downs-of-erlang/

In functional programming, once you set a variable it is immutable, generally, so you don't create lots of new objects. Through recursion you will find that you will have fewer variables, so the garbage collection becomes more important, which may help resolve the memory issues you are having.

But, you would need to see if your problem will work well in FP, as it is not the best language for all situations.

James Black
Hi James, thanks for the pointers. I don't understand one point: when objects are immutable, you *have* to create lots of them, in fact one new instance per new value. My experience is that you create a lot more objects when they are immutable. I am wrong?
Carl Seleborg
You do, but the language is optimized for that. That was my point that you can't take converns from OOP and apply it to FP, as the optimizations will be very different. Erlang has a very good garbage collector.
James Black
+4  A: 

Real-time code can dynamically allocate memory, it just has to be more careful about it.

In real hard real-time the dynamic memory handling will just become another of those factors which have to be taken into account when working-out whether the system can do what it has to in the time allotted. Hard is worst-case.

In soft real-time it is usually enough to check that the dynamic memory handling will not take to too much time and result in too long pauses. Soft is average case.

The erlang system just quite a good job for soft real-time apps, the dynamic memory handling is reasonably efficient and normally does not cause any noticeable pauses. And while it will probably introduce some non-determinism this in itself shouldn't you any problems. I mean that if time is important to you then you should anyway be timing the app, for example so that the audio samples "arrive" on time.

It is a completely different question if erlang is the right language for your app. One thing that has not been really optimised is numeric calculations. Erlang can of course do them but it has nowhere the speed of low-level languages. They have generally not been critical to the types of apps for which erlang has been used. But then again there is Wings 3D, an open source subdivision modeler inspired by Nendo and Mirai from Izware, which is written in erlang. So all is not hopeless. :-)

Really the only way to find out is to write a small test and try it out. Another question is what James mentioned, which type of language would you prefer to use?

rvirding
@nvidring, thanks for your answer. Actually, I already had understood your points. What I was wondering was: since Erlang apparently does introduce non-determinism, what does it do that still makes it suitable for soft real-time apps. I know float computation is not its strong domain, but assuming we were building a synthesizer in Erlang, how could we prevent this non-determinism to cause audio drop-outs when the samples don't arrive on time due to some memory allocation that takes a little longer than normal?
Carl Seleborg
A: 

In end Chap 1, Cesarini / Thompson book, which is excellent, it talks about code SLOC difference vs. a C++ telecomm app: 85% of the C++ code is defensive coding, memory management, high-level communications, which are pretty much unnecessary in functionally comparable erlang code.

Take a look if you're in a bookstore or can borrow from somebody.

also read about research into hard realtime apps

http://lambda-the-ultimate.org/node/2954

http://www.scribd.com/doc/415282/05nicosi

Gene T