5

I am currently learning Haskell for fun because I always wanted to see how you design programs in a non object orientated sense.

But I am also researching if it is useful to use Haskell for a game engine. My main concern is the GC.

I know that GHC is concurrent and thread local.

I read that the GC usually pauses between 1ms-5ms. I know that it is different for every program, but still I need some numbers to make some calculations.

Let's say my game runs at 60fps that means every frame needs 0.016666667s of calculation right? A gc pause would increase this to ~0.017666667 which results in 56fps. So it s a performance loss of ~4fps or 7%. For me that is a pretty big hit.

Now I am counting on the thread local GC because I want my game engine to be highly concurrent.

I want to use the Actor model for the game code so every entity will have it's own memory. If I am right this means that every entity has it's own local garbage collection.

But the main problem is still the game engine with it's main loop. Random fps drops of 7% is pretty big.

Are my calculation correct? Any recommendations that you can give me?

Maik Klein
  • 15,548
  • 27
  • 101
  • 197
  • 2
    You assume that the gc is run at each frame calculation. This is probably wrong. – Nicolas Aug 14 '13 at 14:19
  • @Nicolas I don't assume that it will run every frame. I think it will run at some point and then pause it's local thread. But a pause of 1ms results at 60fps in a 4fps drop. I am not sure when it runs, I think there are some parameters that I can tweak though. I still hope that I am wrong. – Maik Klein Aug 14 '13 at 14:22
  • 1
    No, you added 1ms to each frame calculation. It means that you assumed that at *each* frame, you lose 1ms due to the GC. According to your calculation, the GC is called 56 times per seconds, and use 1ms to run. – Nicolas Aug 14 '13 at 14:28
  • 2
    You're also assuming that without factoring in GC, you managed to fill all 1/60 of your second with useful computation. – Daniel Wagner Aug 14 '13 at 15:04
  • Related: http://stackoverflow.com/questions/15236238/current-state-of-haskell-soft-real-time – shang Aug 14 '13 at 15:12

1 Answers1

2

Your calculation is biased.

You're right: 60 fps = 1 frame every 0.0166667 seconds.

Let's suppose (worst case) that the GC pauses the program for 5ms. Each times the GC runs, you lose 0.005. It means that each times the GC is called, you lose 0.333 fps.

To obtain a correct computation, we need to be able to know how often the GC is called, which I don't know and is certainly linked to the amount of data generated by your program.

Nicolas
  • 24,509
  • 5
  • 60
  • 66
  • Thanks, I just have no idea how much garbage I will produce so I can't predict the pause times. This is somehow bad if I start now to write my engine in Haskell and I see in 2 years that the pause times are unacceptable then I have just lost 2 years of my time. (Sort of) – Maik Klein Aug 14 '13 at 14:53
  • Then use C++ or write up a load test the first thing you do. – kqr Aug 14 '13 at 14:56
  • 2
    @MaikKlein You should watch John Carmak's QuakeCon 2013 keynote. He talks about exactly this issue and posits a possible solution. He describes implementing his idea in C++ but I believe you could do what he describes in Haskell by managing textures etc. through C foreign pointers. – asm Aug 14 '13 at 15:28
  • 1
    @AndrewMyers I actually watched this some days ago, that's why I am learning Haskell atm :). I totally missed the gc part. He said it is perfectly viable to make a every frame gc and that is probably what I will do. Thanks – Maik Klein Aug 14 '13 at 17:35