Seite 1 von 1

Memberfunktion als Thread

Verfasst: 27.09.2010, 23:01
von SunCross
Hallo :),
Ich hab vor, in meiner Game-Klasse zwei Threads laufen zu lassen.
1. Der Process-Thread,
2. Der Render-Thread.

Der Sinn:
Die Szene wird weiterhin gerendert, bzw. aktualisiert, egal, ob im Process-Thread gerade was verarbeitet, oder geladen wird. (So der Gedanke)

Nun ist mein Problem, dass man normale, nicht-statische Memberfunktionen nicht als Thread angeben kann.

Lösungsansatz 1:
Die betroffenen Funktionen statisch machen, dadurch hätten diese aber keinen Zugriff mehr auf nicht-statische Variablen.

Lösungsansatz 2:
DIe Funktionen global machen, dann müsste man aber alle Variablen, die durch die Funktionen benutzt werden, entweder als Parameter übergeben, oder man macht alle benutzten Variablen ebenfalls global.

Lösungsansatz 3: (Mein bisheriger Favorit)
Als erstes Lösung 1 durchziehen,
Dann, auch wenns dämlich aussieht, sämtliche Klassenvariablen statisch machen, da es letztlich eh nur eine Instanz von der Klasse gibt.

Sucht euch einfach nen Lösungsansatz aus und findet ihn gut, oder denkt euch eigene aus.
Beides hilft mir :)

Re: Memberfunktion als Thread

Verfasst: 27.09.2010, 23:10
von Krishty
Normalerweise legt man in dem Fall eine statische Funktion an, die Einsprungspunkt des Threads ist und eine Instanz als Parameter nimmt. Die tut dann nichts anderes, als über diese Instanz die „wahre“ Thread-Member-Funktion aufzurufen.

Code: Alles auswählen

class CThread {
    …

    void ThreadLoop();

    static void StartThreadLoop(CThread & Instance) {
        return Instance.ThreadLoop();
    }

public:

    void Run() {
       CreateThread(StartThreadLoop, *this); // "StartThreadLoop" als Einstiegspunkt, "*this" als Parameter -- Syntax so ähnlich, je nachdem, wie Threads bei dir realisiert werden
    }

};

…

CThread RenderThread;
RenderThread.Run();
Gruß, Ky

Re: Memberfunktion als Thread

Verfasst: 28.09.2010, 13:46
von Helmut
Das willst du jetzt wahrscheinlich nicht hören, aber es ist im Allgemeinen keine gute Idee fürs Rendering einen eigenen Thread zu erstellen. Zum einen kann der Renderthread nichts neues Rendern, wenn der Spielstatus sich nicht verändert hat. (Ob der selbe Frame mit 100 oder 0fps gerendert wird macht nicht wirklich einen Unterschied) Zum anderen gehen sämtliche DX Calls mehr oder weniger direkt zur Grafikkarte, welche unabhängig von der CPU rechnet. Der Overhead durch die anfallende Synchronisierung und erst der Arbeitsaufwand für so eine Implementierung würde sich also niemals wett machen.
Wenn man mit der CPU rendert siehts natürlich anders aus, aber wer macht das schon?:)

Ciao

Re: Memberfunktion als Thread

Verfasst: 28.09.2010, 14:13
von Schrompf
Widerspruch: unsere Engine verbringt inzwischen knapp 50% der Rechenzeit nur in DX-Calls. Wenn man die auf einen separaten Core schieben könnte, hätten wir doppeltes Tempo. Wir sind CPU-limitiert.

Das Problem ist eher, dass DirectX aus dem selben Thread aufgerufen werden muss, in dem auch die Windows-Message-Loop läuft. Du müsstest also alle weitere Logik in einen parallelen Thread schieben und im Primärthread nur DX aus einer Message Queue füttern. Jegliche DX-Calls müssen von da kommen - das ist ein ziemlicher logistischer Aufwand.

Re: Memberfunktion als Thread

Verfasst: 28.09.2010, 15:01
von Lynxeye
Wenn ich falsch liege verbessert mich, aber wurden nicht genau diese Multithreadingmöglichkeiten mit DX10 verbessert? Aber ich kann bestätigen, dass man sehr viel CPU Zeit in GrafikAPI Calls verbringen kann.

Re: Memberfunktion als Thread

Verfasst: 28.09.2010, 15:23
von Krishty
Lynxeye hat geschrieben:Wenn ich falsch liege verbessert mich, aber wurden nicht genau diese Multithreadingmöglichkeiten mit DX10 verbessert?
Das Einzige, worauf man bei D3D10+ achten muss, ist:
For example, if an application that has its message pump on one thread and its rendering on another, it may want to change modes. The message pump thread tells the rendering thread to change modes, and waits until the mode change is complete. However, the rendering thread calls DXGI functions, which in turn call SendMessage, which blocks until the message pump processes the message. A deadlock occurs because both threads now are blocked, and are waiting on each other. To avoid this, never block the message pump. If a block is unavoidable, then all DXGI interaction should occur on the same thread as the message pump.
(Quelle) Ob das nun genauso viel oder weniger als zu D3D9-Zeiten ist, weiß ich aber nicht.

Re: Memberfunktion als Thread

Verfasst: 28.09.2010, 17:37
von SunCross
Erstmal danke für die Antworten.

Meine Idee war Ablauftechnisch geplant.

Im Nachhinein komm ich nicht mehr darauf, wie ich das mit Threads machen wollte.
Ich hab z.B. nie ganz verstanden, wie man einen gewissen Ablauf von gewissen Dingen macht.

Ich mein damit z.B. in einem Rollenspiel, in dem man kämpfen, rumlaufen und mit NPCs reden kann, sind da jetzt sämtliche möglichen Aktionen dauerhaft im GameLoop, oder werden die dazu benötigten Code-Teile z.B. per Funktionszeiger umgestellt?

Und wenn es im Spiel eine einmalige Aktion gibt, die es im Spiel nur einmal gibt, wie z.B. wenn sich was am Terrain ändert, das aber dauerhaft so bleibt, wird die Abfrage, ob die Geländeänderung nun stattfinden soll, immer weiter abgefragt, bleibt also im aktiven Code?

Das würd mich mal interessieren, die Threads waren für mich sowas wie ein Versuchsansatz. (Der mir im Nachhinein aber selber sinnlos erscheint)

Re: Memberfunktion als Thread

Verfasst: 28.09.2010, 19:03
von eXile
SunCross hat geschrieben:Ich mein damit z.B. in einem Rollenspiel, in dem man kämpfen, rumlaufen und mit NPCs reden kann, sind da jetzt sämtliche möglichen Aktionen dauerhaft im GameLoop, oder werden die dazu benötigten Code-Teile z.B. per Funktionszeiger umgestellt?
Normalerweise hat man ein Entity-System, welches einem genau sagt, wann die nächsten Events anstehen. Aber ob Events anstehen wird natürlich in jedem Frame via if-Abfrage überprüft. Warum auch nicht: Heutzutage kann man Millionen von solchen Abfragen pro Frame verarbeiten.
SunCross hat geschrieben:Und wenn es im Spiel eine einmalige Aktion gibt, die es im Spiel nur einmal gibt, wie z.B. wenn sich was am Terrain ändert, das aber dauerhaft so bleibt, wird die Abfrage, ob die Geländeänderung nun stattfinden soll, immer weiter abgefragt, bleibt also im aktiven Code?
Die Abfrage wird immer stattfinden. Aber häufig kann man mehrere Abfragen zu einer großen Abfrage zusammenfassen: Das Spiel wird z.B. immer einen bestimmten Game-State haben, z.B. Hauptmenü, Spiel, Abschlussbildschirm, usw. Dann wird einfach einmal der Game-State abgefragt, und man muss einen Haufen if-Abfragen für das Hauptmenü gar nicht mehr überprüfen, wenn man im eigentlichen Spiel ist! Das ist das ganze Konzept von verschachtelten if-Abfragen. ;)

Re: Memberfunktion als Thread

Verfasst: 28.09.2010, 20:55
von SunCross
Leider hab ich noch was von einem Entity-System gehört :oops: ,
das Internet hat mir auch keine wirkliche Erklärung gegeben, sondern nur Diskussionen.
Ist das sowas wie eine Nachrichtenschleife, die von ausserhalb Nachrichten geschickt bekommt?
Z.B. die Spielfigur nähert sich einem gesprächsbereiten NPC, der NPC schickt nun die Nachricht, dass ein Gespräch beginnen kann.
Anhand der Nachricht kann man nun anzeigen lassen, dass man eine Taste drücken muss, um das Gespräch zu starten. Wenn die Taste gedrückt wird, kommt die zweite Nachricht, die angibt, dass das Gespräch nun beginnt.

So in etwa?

Die Nachrichtenliste könnte man in eine Klasse packen, die die Liste per Funktion an alle interaktiven Objekte weiterreicht, damit diese die Nachrichten direkt in die Liste einfügen können.

Re: Memberfunktion als Thread

Verfasst: 28.09.2010, 21:34
von Krishty
Nein, die Spielfigur hat eine Membervariable, die angibt, ob der Spieler in ein Gespräch verwickelt ist (und noch eine, die dann sagt, mit wem). Wenn der Spieler die Taste drückt, wird diese Variable gesetzt und bleibt es auch, bis der Spieler irgendwann in einem späteren Frame den Dialog beendet. Anhand der Variable erkennt der Renderer dann auch, ob er den Dialogtext über den Bildschirm rendern soll oder nicht.

Darüber könnte man natürlich noch viel mehr diskutieren, z.B. den Spieler als Automat sehen, wobei ein Zustand „Dialog“ ist und der Tastendruck ein Übergang.

Re: Memberfunktion als Thread

Verfasst: 28.09.2010, 21:48
von SunCross
Ok, ich pack mal meinen alten SDL-Framework und probier die ganze Kiste mit 2D-Grafik aus.

Dafür brauchts keine 3D-DirectX-Grafik und mit DirectX hab ich noch keinen 2D-Framework gebaut :)

Danke an alle.

PS.: Gibts eigentlich Bücher zu dem Thema?

Re: Memberfunktion als Thread

Verfasst: 02.10.2010, 16:01
von odenter
Ist der Sinn von Events nicht auf Sie zu reagieren wenn Sie kommen, und nicht per Abfrage ständig zu prüfen ob eins anliegt?

Re: Memberfunktion als Thread

Verfasst: 02.10.2010, 21:16
von eXile
odenter hat geschrieben:Ist der Sinn von Events nicht auf Sie zu reagieren wenn Sie kommen, und nicht per Abfrage ständig zu prüfen ob eins anliegt?
Man hat so wie so die ganze Zeit eine Endlosschleife laufen, also warum nicht das gleich abfragen? Der Sinn der Ereignisorientierten Programmierung ist ja häufig, dass sich einfach ein Thread, solange kein Ereignis passiert, schlafen legen kann. Das würde hier kaum Sinn ergeben - zumal die dabei auftretende Inversion of Control das System komplexer machen würde. ;)

(Eventuell GUI-Systeme mal ausgenommen. Aber auch da gibt es sehr unterschiedliche Ansätze. )