我正在考虑将Haskell用于软实时应用。我可能会使用演员,这是值得的。我想知道是否有人了解Haskell的当前实时状态。具体来说,GC暂停应用程序的问题。我已经广泛搜索过,而且我在2年多前发现了大量的讨论,但没有任何最新内容。以下是我发现的几个参考文献:
Using Haskell for sizable real-time systems: how (if?)?
How about Haskell's GC performance for soft realtime application like games?
我读过的很多旧东西都表明情况(当时)被认为正在改善。有吗?
即使在2年多前,也有一些评论表明可以调整Haskell应用程序,以便可靠地将GC暂停降低到一毫秒或两秒。这看起来真实吗?
答案 0 :(得分:31)
因此,对“实时”的关注是GC集合引入的延迟。
GHC使用多核垃圾收集器(a branch有per-thread local heaps)。最初开发是为了通过降低频繁停止世界同步的成本来提高多核性能(每个核心can collect independently),出于同样的原因,这也有利于软实时。但是,截至2013年,每个线程的本地堆尚未合并到主GHC中,尽管并行GC已经存在。
对于游戏,您应该能够通过使用线程来利用它,从而减少对世界本地收藏的需求。
对于长寿命对象,在全局堆中,您仍会冒一些(ms)GC的风险。但是,仔细分析例如ThreadScope将在此处消除障碍。我已经看到通过GHC管理的网络堆栈流式传输实时1080p视频而没有明显的GC暂停。
即使没有这些调整,事情“可能正常”。 Frag几乎不需要优化,而且近10年前的实时性很强。
最后,有许多工具和GHC标志可以提高性能:
然后有编码:使用未装箱的类型(没有GC),最小化惰性结构分配。以包装形式保存长寿数据。测试和基准测试。
我觉得你没事。
答案 1 :(得分:7)
你见过这些:
另外,我建议您联系Multicore Garbage Collection with Local Heaps论文(ISMM 2011)的作者。
答案 2 :(得分:2)
我没有遇到GC暂停的问题,只要你不为所有内容使用惰性列表,就不应该生成太多垃圾。
然而,对于多线程应用程序来说,Sky并不是那么光明。 GHC仍然没有具有线程优先级的调度程序,如果你使用线程进行繁重的后台处理,你很容易使事件循环挨饿。答案 3 :(得分:1)
GHC 8.2.1有一个称为紧凑区域的功能,可能会有所帮助。
据我了解,它似乎是一种半手动内存管理。 您可以在Compact区域中存储长期存在的数据,垃圾收集器不会跟踪它。如果在Compact区域中有任何引用,则整个Compact区域保持活动状态。一旦没有对该地区的任何内容的引用,它将被解除分配。如果您对区域的内容进行功能更新,则可以在新区域中重新分配它,并且将释放旧区域。
http://ezyang.com/compact.html
https://hackage.haskell.org/package/compact-0.1.0.1/docs/Data-Compact.html