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:
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.
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?
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?
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?
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With