2013-08-14 4 views
5

Ich lerne gerade Haskell zum Spaß, weil ich immer sehen wollte, wie Sie Programme in einem nicht objektorientierten Sinn entwerfen.GC pausiert in Haskell für weiche Echtzeitanwendungen

Aber ich recherchiere auch, ob es nützlich ist, Haskell für eine Spielengine zu verwenden. Mein Hauptanliegen ist der GC.

Ich weiß, dass GHC gleichzeitig und lokal Thread ist.

Ich lese, dass der GC in der Regel zwischen 1ms-5ms pausiert. Ich weiß, dass es für jedes Programm anders ist, aber ich brauche noch ein paar Zahlen, um ein paar Berechnungen zu machen.

Lassen Sie uns sagen, mein Spiel läuft bei 60fps, das bedeutet, dass jedes Bild 0.016666667s der Berechnung oder? Eine GC-Pause würde dies auf ~0.017666667 erhöhen, was zu 56fps führt. Es ist also ein Leistungsverlust von ~4fps oder 7%. Für mich ist das ein ziemlich großer Erfolg.

Jetzt zähle ich auf den Thread lokalen GC, weil ich möchte, dass meine Spiel-Engine hochgradig gleichzeitig ist.

Ich möchte das Actor-Modell für den Spielecode verwenden, damit jede Entity ihren eigenen Speicher hat. Wenn ich recht habe, bedeutet dies, dass jede Entity ihre eigene lokale Garbage Collection hat.

Aber das Hauptproblem ist immer noch die Game Engine mit ihrer Hauptschleife. Zufällige fps-Tropfen von 7% sind ziemlich groß.

Sind meine Berechnungen korrekt? Irgendwelche Empfehlungen, die Sie mir geben können?

+2

Sie nehmen an, dass der GC bei jeder Rahmenberechnung ausgeführt wird. Das ist wahrscheinlich falsch. – Nicolas

+0

@Nicolas Ich gehe nicht davon aus, dass es jeden Frame laufen wird. Ich denke, es wird irgendwann laufen und dann seinen lokalen Thread pausieren. Aber eine Pause von 1ms ergibt bei 60fps in einem 4fps Drop. Ich bin mir nicht sicher, wann es läuft, ich denke, es gibt einige Parameter, die ich optimieren kann. Ich hoffe immer noch, dass ich falsch liege. –

+1

Nein, Sie haben jeder Rahmenberechnung 1ms hinzugefügt. Es bedeutet, dass Sie angenommen haben, dass Sie bei * jedem * Rahmen aufgrund des GC 1 ms verlieren. Gemäß Ihrer Berechnung wird der GC 56 mal pro Sekunde aufgerufen und verwendet 1 ms zum Ausführen. – Nicolas

Antwort

2

Ihre Berechnung ist voreingenommen.

Sie haben recht: 60 fps = 1 Bild alle 0,0166667 Sekunden.

Nehmen wir an (schlimmsten Fall), dass der GC das Programm für 5 ms pausiert. Jedes Mal, wenn der GC ausgeführt wird, verlieren Sie 0,005. Das bedeutet, dass Sie jedes Mal, wenn der GC aufgerufen wird, 0,333 fps verlieren.

Um eine korrekte Berechnung zu erhalten, müssen wir wissen können, wie oft der GC aufgerufen wird, was ich nicht weiß und sicherlich mit der Menge der von Ihrem Programm erzeugten Daten verbunden ist.

+0

Danke, ich habe nur keine Ahnung, wie viel Müll ich produzieren werde, so kann ich die Pause nicht vorhersagen mal. Das ist irgendwie schlecht, wenn ich jetzt anfange, meine Engine in Haskell zu schreiben und ich sehe in 2 Jahren, dass die Pausenzeiten inakzeptabel sind, dann habe ich gerade 2 Jahre meiner Zeit verloren. (Sortieren von) –

+0

Dann verwenden Sie C++ oder schreiben Sie einen Lasttest als erstes, was Sie tun. – kqr

+2

@MaikKlein Sie sollten sich John John Carmak's QuakeCon 2013 Keynote ansehen. Er spricht über genau dieses Thema und postuliert eine mögliche Lösung. Er beschreibt die Implementierung seiner Idee in C++, aber ich glaube, Sie könnten das tun, was er in Haskell beschreibt, indem Sie Texturen usw. durch C fremde Zeiger verwalten. – asm