一些背景
我正在为数字媒体编程构建一种编程语言,它应该支持使用无共享消息传递和软实时的并发性(即尽量计算音频/视频而不丢失样本或帧并且具有恒定的吞吐量) 。
事实证明,这两个特征难以组合,主要是因为一个特定的约束:实时代码不应动态分配内存。
我的语言应该可以很容易地实现这样的事情:
- 一个线程根据参数计算音频样本。例如,这些可以是合成器的不同控制的值。该线程“实时”运行。
- 一个线程接收来自用户或另一台计算机的输入以更改这些值。例如,这可以是GUI线程,对用户用鼠标转动旋钮作出反应。
我希望用户设置的新值通过队列发送到合成器引擎。现在,如果我只想发送浮点数和其他原子值,问题就不会有意思了。实际上,我想要 任何 一种数据能够从一个线程流向另一个线程,甚至是复杂的对象或数据结构,这对于线程和优先级的任何配置都应该是可能的。如果没有实时动态内存分配,这就变得非常困难,而不会对程序员施加任何似乎任意的限制。
Erlang经常被宣传为适合实时系统。我的理解是,Erlang从不会禁止内存分配。如果我做了同样的事情,那将会导致许多问题消失,代价是在执行这些分配的代码中引入非确定性时序。
这个问题
那么是什么让Erlang如此合适呢?它是否实现了特殊的技巧来规避内存分配引起的问题,还是完全忽略了这个问题?它需要另一种实时方法吗?
举例说明这个问题
让我们假设我们在Erlang中编写一个合成器,它必须每50毫秒产生64个样本,否则声音中会出现裂缝和爆裂声。让我们假设当我在字符串上移动一些滑块时,一个小对象(假设它是一个列表或包含参数名称和新值的元组)必须从GUI进程发送到音频进程,其中a副本已创建。这将需要动态内存分配。 Erlang如何帮助我确保此分配不会延迟我的音频计算?
实时代码 能够 动态分配内存,只需要更加小心。
现实 硬 实时动态内存处理将成为另一个因素,在确定系统是否能够在分配的时间内完成所需的工作时必须考虑这些因素。艰难是最坏的情况。
在 柔软的 实时通常足以检查动态内存处理不会占用太多时间并导致暂停时间过长。软是平均情况。
erlang系统对于软实时应用程序来说是一个相当不错的工作,动态内存处理相当有效,并且通常不会引起任何明显的暂停。虽然它可能会介绍 一些 非决定论这本身不应该是你的任何问题。我的意思是,如果时间对你很重要,那么你应该对应用进行计时,例如以便音频样本按时“到达”。
如果erlang是您的应用的正确语言,这是一个完全不同的问题。尚未真正优化的一件事是数值计算。 Erlang当然可以做到,但它没有低级语言的速度。它们通常对使用erlang的应用程序类型并不重要。但是又有一个Wings 3D,一个开源的细分模型,灵感来自Izndo的Nendo和Mirai,用erlang编写。所以一切都不是没有希望的。 :-)
真正找到答案的唯一方法是编写一个小测试并试一试。另一个问题是詹姆斯提到的,你更喜欢使用哪种语言?
实时代码 能够 动态分配内存,只需要更加小心。
现实 硬 实时动态内存处理将成为另一个因素,在确定系统是否能够在分配的时间内完成所需的工作时必须考虑这些因素。艰难是最坏的情况。
在 柔软的 实时通常足以检查动态内存处理不会占用太多时间并导致暂停时间过长。软是平均情况。
erlang系统对于软实时应用程序来说是一个相当不错的工作,动态内存处理相当有效,并且通常不会引起任何明显的暂停。虽然它可能会介绍 一些 非决定论这本身不应该是你的任何问题。我的意思是,如果时间对你很重要,那么你应该对应用进行计时,例如以便音频样本按时“到达”。
如果erlang是您的应用的正确语言,这是一个完全不同的问题。尚未真正优化的一件事是数值计算。 Erlang当然可以做到,但它没有低级语言的速度。它们通常对使用erlang的应用程序类型并不重要。但是又有一个Wings 3D,一个开源的细分模型,灵感来自Izndo的Nendo和Mirai,用erlang编写。所以一切都不是没有希望的。 :-)
真正找到答案的唯一方法是编写一个小测试并试一试。另一个问题是詹姆斯提到的,你更喜欢使用哪种语言?
由于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中运行良好,因为它不是适用于所有情况的最佳语言。
最后的第1章,Cesarini / Thompson这本书非常出色,它讨论了与C ++电信应用程序相比的代码SLOC差异:85%的C ++代码是防御性编码,内存管理,高级通信,这几乎是不必要的在功能相当的erlang代码中。
看看你是在书店还是可以向某人借钱。
还阅读有关硬实时应用程序的研究
http://lambda-the-ultimate.org/node/2954
http://www.scribd.com/doc/415282/05nicosi
我真的不同意这个问题。这要求太多了。
“......这需要动态内存分配.Erlang如何帮助我确保这种分配不会延迟我的音频计算?”。
工具(Erlang或任何其他语言)不太可能提前为您提供此保证。
一直使用的方法是定时测试或基准测试。
如果您想证明您的代码不会延迟您的音频计算,您可能需要自己构建此证明。但证据中的步骤可能依赖于之前的时序测试。