Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

Schrompf

Alter Hase

Beiträge: 1 470

Wohnort: Dresden

Beruf: Softwareentwickler

  • Private Nachricht senden

11

09.07.2015, 16:34

Stimmt, so wie Du es beschreibst, sollte es auch gehen. Der Hauptthread gründet einen Zweitthread mit opt(Q), macht dann selber opt(P) und wenn er damit fertig ist, joint er den Zweitthread. Wenn also opt(Q) schon fertig ist, kehrt join() sofort zurück und Du müsstest effektiv P und Q parallel ausgeführt haben.

Bleibt also die Frage, warum er das nicht tut. Du hast nachgemessen und wirklich festgestellt, dass die parallele Variante länger oder gleich lang arbeitet als die kurze Variante? Und Du hast auch wirklich sichergestellt, dass P und Q in Deinem Fall wirklich beide ausgeführt werden? Und das beide Aufgaben in etwa gleich lang arbeiten? Sorry wenn das jetzt albern klingt, aber ich stochere hier im Dunkeln; und manches Mal liegt es an den albernsten Sachen, die man nur vergessen hat zu prüfen.

Und wie gesagt: es kann auch sein, dass die Funktionen, die Du da parallel auszuführen versuchst, beide jeweils einen Mutex ziehen, weil sie auf irgendnem globalen Zustand arbeiten. Prüfe das nach, indem Du mal in die Quellen der Funktionen schaust oder mit dem Debugger mal reinsteppst. Wenn das der Fall ist, kannst Du Dir nämlich jede Parallelisierung sparen.
Häuptling von Dreamworlds. Baut aktuell an nichts konkretem, weil das Vollzeitangestelltenverhältnis ihn fest im Griff hat. Baut daneben nur noch sehr selten an der Open Asset Import Library mit.

Tobiking

1x Rätselkönig

  • Private Nachricht senden

12

09.07.2015, 17:32

Ok, ich habe auch übersehen das dort in dem Mainthread auch noch etwas gemacht wird. Es kann durchaus sein, dass die Optimierung gar nicht lang genug braucht das sich die Threaderstellung lohnt. Da müsstest du mal messen wie lange die einzelnen Optimierungsdurchgänge für P und Q dauern. Du sparst dabei ja auch immer nur das Minimum der beiden Zeiten.

13

10.07.2015, 18:02

Ja, ich habe mir das nochmal angeguckt und die Threaderstellung lohnt sich einfach nicht. Ich brauche etwa 1 ms für die Optimierung eines Q's. Ich denke, dass da dann die Threaderstellung einfach negativ ins Gewicht fällt. Ich müsste wohl selber so eine Art Threadpool schreiben, damit sich das eventuell lohnt (CRT kann ich nicht nutzen).

Sry, noch den letzten Teil deiner Frage vergessen Schrompf: Die Threads greifen auf alle Sachen nur lesend zu, somit dachte ich mir, dass sich das mit dem Mutex von selbst erübrigt, die einzigen Schreiboperationen finden auf P für den Mainthread und Q für den Zweitthread statt. Der Mainthread fässt dabei Q nie and und der zweite Thread fässt P nie an (also weder schreibender noch lesender Zugriff).

Grüße,
CSharp

Sylence

Community-Fossil

Beiträge: 1 663

Beruf: Softwareentwickler

  • Private Nachricht senden

14

10.07.2015, 18:07

Wie oft machst du denn diese Optimierung?
Wenn du sie öfter machst, dann könnte es sich lohnen einen Thread am laufen zu haben, der sobald es etwas zu berechnen gibt, anfängt zu rechnen und die restliche Zeit schläft.

Wenn das allerdings nur eine ms braucht, dann muss das schon sehr oft berechnet werden, damit sich ein Thread überhaupt lohnt.

15

10.07.2015, 20:10

Die Optimierung wird sehr häufig gemacht. Im Schnitt sinds 10.000 Optimierungen von Q's. Deshalb dacht ich mir das auch mit dem Thread. Was ich probiert habe, ist, meiner Klasse, die die Optimierung durchführt, eine Membervariable boost::thread m_Thread zu geben, sodass nicht immer ein neuer Thread erzeugt werden muss. Allerdings gibt es iwie in C++ nicht die Möglichkeit (jedenfalls habe ich nichts entsprechendes finden können), zu sagen:

//Sei m_Thread die private boost::thread variable meiner Klasse MyClass

m_Thread.Start( /* lambda function here */);

Falls es so etwas jedoch gibt, wäre es cool, wenn jmd auch etwas source code posten könnte :).


Grüße,
CSharp

Schrompf

Alter Hase

Beiträge: 1 470

Wohnort: Dresden

Beruf: Softwareentwickler

  • Private Nachricht senden

16

10.07.2015, 20:28

Nee, was Du eher willst, ist std::condition_variable oder das boost-Äquivalent. Gib dem Thread eine Arbeitsfunktion, die in einer Schleife jeweils einen Job (std::function<void()>) aus einer Queue (boost::concurrent_queue oder so) zieht und ausführt. Wenn kein Job da ist, wartet der Thread stattdessen auf einer condition_variable. Und vom Producer Thread aus stopfst Du dann jeweils Lambdas in die Queue, die ihre Parameter per Capture mitnehmen, und weckst dann einen der Worker Threads mit condition_variable::notify_one().

Genau sowas hab ich übrigens neulich für mein Spiel geschrieben. Dickes Dankeschön an den SPPro-IRC-Kanal, insbesondere xtr1m und BlueCobold, für die interessante Diskussion. Ich habe mal wieder viel gelernt.

Es würde sich für Dich übrigens lohnen, wenn Du alle Ps und Qs gleichzeitig im Speicher hast, dann auf alle nacheinander die Optimierungen anwendest, und erst danach parallel jeweils einmal P und Q kombinierst. Das wär dann ein klassisches datenparalleles Arbeiten, das man phantastisch auf x CPU-Kerne aufteilen kann. Die wenigsten Coder haben das Glück, so freundlich parallelisierbare Aufgaben zu kriegen :-)
Häuptling von Dreamworlds. Baut aktuell an nichts konkretem, weil das Vollzeitangestelltenverhältnis ihn fest im Griff hat. Baut daneben nur noch sehr selten an der Open Asset Import Library mit.

Helmut

5x Contest-Sieger

Beiträge: 692

Wohnort: Bielefeld

  • Private Nachricht senden

17

12.07.2015, 12:49

Das Framework vom BlobbyVolley Contest, das ich geschrieben habe, implementiert genau das, was du hier scheinbar tun willst. Der Code ist auch recht einfach gehalten. Es wird die eine KI auf dem Mainthread ausgeführt und die andere in einem Workerthread, wobei der Thread nur am Anfang gestartet wird und nicht immer wieder neu.
Sei stets geduldig gegenüber Leuten, die nicht mit dir übereinstimmen. Sie haben ein Recht auf ihren Standpunkt - trotz ihrer lächerlichen Meinung. (F. Hollaender)

Werbeanzeige