Haskell中的GC暂停对于软实时应用程序的影响

5

我目前在学习Haskell,只是出于兴趣,因为我想看看如何以非面向对象的方式设计程序。

但我还在研究是否有用使用Haskell来开发游戏引擎。我的主要问题是GC(垃圾回收)。

我知道GHC是并发和线程本地的。

我读过GC通常会在1ms-5ms之间暂停。我知道这对每个程序都不同,但我仍需要一些数字来进行计算。

假设我的游戏以60fps运行,这意味着每帧需要0.016666667s的计算时间对吗?GC暂停会将这个时间增加到~0.017666667,这将导致56fps。所以这是~4fps7%的性能损失。对我来说,这是一个相当大的打击。

现在我依靠线程本地GC,因为我希望我的游戏引擎高度并发。

我想为游戏代码使用Actor模型,因此每个实体都将拥有自己的内存。如果我没记错的话,这意味着每个实体都有自己的本地垃圾回收。

但主要问题仍然是游戏引擎及其主循环。7%的随机fps下降相当大。

我的计算正确吗?你能给我一些建议吗?


2
你假设垃圾回收在每个帧计算时运行。这可能是错误的。 - Nicolas
@Nicolas 我并不认为它会在每一帧都运行。我认为它会在某个时刻运行,然后暂停它的本地线程。但是1毫秒的暂停在60fps下会导致4fps的降低。我不确定它何时运行,但我认为有一些参数可以调整。我仍然希望我是错的。 - Maik Klein
1
不,你在每个帧计算中都加了1毫秒。这意味着你假设在每个帧中,由于GC而丢失1毫秒。根据你的计算,GC每秒调用56次,并使用1毫秒运行。 - Nicolas
2
你还假设在没有考虑垃圾收集的情况下,你成功地用1/60秒填满了所有有用的计算。 - Daniel Wagner
相关:https://dev59.com/FWUp5IYBdhLWcg3wf3us的当前状态 - shang
1个回答

2

你的计算存在偏差。

没错:60 fps = 每0.0166667秒1帧。

假设(最坏情况)GC暂停程序5毫秒。每次GC运行,你会损失0.005。这意味着每次调用GC时,你会损失0.333 fps。

为了得到正确的计算结果,我们需要知道GC被调用的频率,但我不知道,这肯定与你的程序生成的数据量有关。


谢谢,我不知道我会产生多少垃圾,所以我无法预测暂停时间。如果我现在开始用Haskell编写我的引擎,并且在两年后发现暂停时间不可接受,那么我就浪费了两年的时间。(有点糟糕) - Maik Klein
然后使用C++或编写负载测试是你要做的第一件事。 - kqr
2
@MaikKlein 你应该观看John Carmak在QuakeCon 2013的主题演讲。他谈到了这个问题,并提出了可能的解决方案。他描述了如何在C++中实现他的想法,但我相信你可以通过管理纹理等来使用C外部指针在Haskell中实现他所描述的内容。 - asm
1
@AndrewMyers 我几天前实际上就看了这个,所以现在我正在学习 Haskell :). 我完全错过了垃圾回收部分。他说每帧进行垃圾回收是完全可行的,这可能是我要做的。谢谢 - Maik Klein

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