什么使得Erlang适用于软实时应用?

9

一些背景

我正在开发一种数字媒体编程语言,它应该支持并发,使用无共享消息传递和软实时(即尽最大努力计算音频/视频,不会丢失样本或帧,并具有恒定的吞吐量)。

事实证明,这两个特性结合起来非常困难,主要是因为一个特定的限制:实时代码不应该动态分配内存。

我的语言应该使实现以下内容变得容易:

  • 一个线程根据参数计算音频样本。这些可以是合成器不同控件的值,例如。此线程“实时”运行。
  • 一个线程从用户或另一台计算机接收输入以更改这些值。这可能是GUI线程,例如,响应用户用鼠标旋转旋钮。

我希望由用户设置的新值通过队列发送到合成器引擎。如果我只想发送浮点数和其他原子值,则问题不会有趣。实际上,我希望任何类型的数据都能够从一个线程流向另一个线程,甚至是复杂对象或数据结构,并且这对于任何线程和优先级配置都是可能的。在实时侧没有动态内存分配,这变得非常困难,而不会对程序员施加看似任意的限制。

Erlang通常被宣传为实时系统的良好选择。我的理解是,Erlang从不禁止内存分配。如果我也这样做,那么很多问题就会消失,但代价是在执行这些分配的代码中引入非确定性时间。

问题

那么,什么使Erlang如此适合?它是否实现了特殊技巧来规避内存分配引起的问题,还是完全忽略了该问题?它是否采用了另一种实时方法?

一个例子来说明问题

假设我们正在使用Erlang编写一个合成器,它必须每50毫秒产生64个样本,否则声音会出现噼啪声。假设当我在字符串上移动滑块时,GUI进程必须发送一个小对象(假设它是包含参数名称和新值的列表或元组)到音频进程,其中创建了一个副本。这将需要动态内存分配。Erlang如何帮助我确保此分配不会延迟我的音频计算?

4个回答

11

实时代码可以动态分配内存,但需要更加小心谨慎。

硬实时中,动态内存处理只是必须考虑的因素之一,以确定系统是否能够在规定时间内完成任务。"Hard"是最坏情况。

软实时中,通常只需检查动态内存处理不会花费过多时间并导致太长的暂停即可。"Soft"是平均情况。

Erlang 系统对于软实时应用程序做得非常好,动态内存处理效率合理,通常不会导致任何明显的暂停。虽然这可能会引入一些不确定性,但这本身不应该给您带来任何问题。我的意思是,如果时间对您很重要,那么您应该始终计时应用程序,例如使音频样本按时"到达"。

另一个完全不同的问题是 erlang 是否适合您的应用程序。一个未真正优化的方面是数值计算。当然,Erlang 可以做到,但速度远不及低级语言。它们通常对 erlang 使用的应用程序类型不是关键因素。但还有 Wings 3D,这是一个开源的子模型编辑器,灵感来自 Izware 的 Nendo 和 Mirai,它是用 erlang 编写的。所以一切并非没有希望。:-)

真正找出答案的唯一方法是编写一个小测试并尝试一下。另一个问题是 James 提到的,您更喜欢使用哪种类型的语言?


@nvidring,感谢您的回答。实际上,我已经理解了您的观点。我想知道的是:既然Erlang显然引入了非确定性,那么它做了什么使其仍适用于软实时应用程序。我知道浮点计算不是它的强项,但是假设我们正在使用Erlang构建合成器,我们如何防止这种非确定性导致音频中断,当样本由于某些内存分配需要比正常时间长一点时没有按时到达? - Carl Seleborg

4
由于Erlang是由Ericcson Communications为电信使用而创建的,因此快速和可扩展性是重要考虑因素。
您可能希望查看此文章,了解尝试使Erlang准备好用于硬实时应用程序时需要克服的问题。 http://lambda-the-ultimate.org/node/2954 您可能会发现,仍然存在的某些问题可能也会成为您的应用程序的障碍。
您可能还会发现这个有趣,因为FP与OOP不同,因此您在OOP中遇到的一些问题将在FP领域中有所不同。 http://blog.ribomation.com/2009/06/28/the-ups-and-downs-of-erlang/ 在函数式编程中,一旦设置变量,它就是不可变的,通常不会创建大量新对象。通过递归,您会发现变量更少,因此垃圾收集变得更加重要,这可能有助于解决您遇到的内存问题。
但是,您需要查看您的问题是否适合FP,因为它并不是所有情况下最好的语言。

嗨詹姆斯,感谢你的指引。我不明白其中一个点:当对象是不可变的时候,你必须创建很多实例,事实上每个新值都需要创建一个新实例。我的经验是,当它们是不可变的时候,你会创建更多的对象。我错了吗? - Carl Seleborg
你是对的,但语言是为此进行了优化的。我的观点是你不能将面向对象编程的问题应用到函数式编程中,因为优化方式会有很大不同。Erlang拥有非常好的垃圾回收机制。 - James Black

1
在 Cesarini / Thompson 的优秀书籍第一章的结尾部分,它谈到了代码行数(SLOC)差异与一个 C++ 电信应用程序:85% 的 C++ 代码是防御性编码、内存管理和高级通信,这在功能上可与 erlang 代码相比几乎是不必要的。 如果你在书店或可以借阅的话,可以看一下。
还可以阅读有关硬实时应用程序的研究。

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

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


0

我实在不同意这个问题。它要求的太多了。

"... 这需要动态内存分配。Erlang如何帮助我确保这种分配不会延迟我的音频计算呢?"。

很可能不存在(在Erlang或任何其他语言中)可以事先向您提供这种保证的工具。

一直以来使用的方法是进行时间测试或基准测试。

如果您想证明您的代码不会延迟您的音频计算,您可能需要自己构建这个证明。但证明中的步骤可能依赖于先前的时间测试。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接