Adam's Lair Forum

game development and casual madness
It is currently 2019/09/17, 15:13

All times are UTC + 1 hour [ DST ]




Post new topic Reply to topic  [ 4 posts ] 
Author Message
PostPosted: 2013/11/27, 12:32 
Novice Member
Novice Member

Joined: 2013/05/21, 17:47
Posts: 14
Role: Professional
Hi peoples

I am going to start to test some ways to multi-thread the engine. The first thing I m thinking of trying is to split the update and drawing, then sync using double buffer or similar.
I was wondering if you had any thoughts about it?

Cheers


Top
 Profile  
 
PostPosted: 2013/11/27, 13:57 
Site Admin
Site Admin
User avatar

Joined: 2013/05/11, 22:30
Posts: 2073
Location: Germany
Role: Professional
Hey roundcrisis,

as you know, there is currently only one part of the engine being run in a (set of) separate thread(s), which is audio streaming. This works exceptionally well, because it is so clearly separated from everything else and has next to zero data dependency. To introduce more parallelism, I basically see three (rather general) approaches:

  1. Identify other, similarly isolated chunks of code and move them to a separate thread. Example: Audio Streaming.
  2. Artificially separate not-so-isolated chunks of code from the rest by means of double-buffering. Probably impractical thought experiment: GameObject Double Buffering
  3. Identify CPU-heavy loops and use Parallel.For. Example: Some Pixmap.Layer operations. Be careful with this one, though - this doesn't mix well with Windows.Forms e.g. Dualitor in all cases, so keep an eye on the context you're using this in.

I don't have much experience with multithreaded OpenGL, but I'd be highly interested in your implementation and results. However, it should help that Duality already separates its drawing code from updating code for the most part. While collecting Drawcalls may be tricky to put in a separate thread, everything happening after that - sort, optimize, submit - shouldn't be a big problem, because all that happens using the previously created drawcall buffer. The only solid links between those and game logic are

  1. the vertex arrays you're specifying in DrawDevice.AddVertices, which are sometimes but not always cloned.
  2. referenced Materials, DrawTechniques, Shaders, etc. which should probably not be modifies while being used for drawing. This rarely happens when running the game, but may very well happen in the editing environment - and might be a problem, because Resources are globally available and thus cannot be restrained from being modified easily. Maybe there is a way to decouple this as well, though.

But again, keep an eye on Dualitor - Windows.Forms isn't very fond of multithreading stuff.

Regards,
Adam

_________________
Blog | GitHub | Twitter (@Adams_Lair)


Top
 Profile  
 
PostPosted: 2013/12/19, 20:52 
Novice Member
Novice Member

Joined: 2013/05/21, 17:47
Posts: 14
Role: Professional
I don't have much news on this, should be looking at this again soon tho


Top
 Profile  
 
PostPosted: 2013/12/25, 13:31 
Site Admin
Site Admin
User avatar

Joined: 2013/05/11, 22:30
Posts: 2073
Location: Germany
Role: Professional
I've given the topic some (very limited) thought in the meantime. Things that could potentially run in parallel - with some limitations - are:

  • Farseer Physics Update
  • GameObject Update
  • Collecting Drawcalls
  • Audio Streaming (already does)
  • Rendering

I would certainly not recommend to apply parallelism to anything that invokes or is invoked by user code, i.e. plugin code in general. In the above case, this means GameObject Updates and Collecting Drawcalls. It could be done and would probably work well, but this would complicate things on the user side by a great deal, since he suddendly has the potential of causing or running into bugs and strange behavior that is caused by threaded operations he did neither start nor know of.

Now, in theory, collecting drawcalls could run in parallel to the above list with some changes to the existing code, but that would mean breaking the above guideline. The same goes for overall GameObject updates - but they can't run in parallel to the Physics Update anyway, due to the RigidBody Component being intertwined with them a lot. This could be changed by rewriting some RIgidBody code, but again, I wouldn't recommend putting anything that could be touched by the user into a different Thread.


Here's a picture of what I'd probably do in a first iteration:
Attachment:
DualityThreadingA.png

Basically, it's just physics put in a different Thread. I'm pretty sure there is a way to put Rendering in a different Thread as well, or rather put "everything else" in a different thread to avoid OpenGL Threading issues, so that'd be the second thing I'd approach. Of course it depends on the workload, whether or not each step will yield notable performance improvements. If you have complex physics, the first iteration will sure help a lot. If you have complex rendering, well, you might skip the physics part then and start directly with parallelizing actual rendering. I would stay away from collecting drawcalls and update though, at least until all the other possibilities are done with.


Of course, you could also try to do this:
Attachment:
DualityThreadingB.png

Doesn't utilize more threads, but puts focus on doing rendering in parallel.

_________________
Blog | GitHub | Twitter (@Adams_Lair)


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 4 posts ] 

All times are UTC + 1 hour [ DST ]


Who is online

Users browsing this forum: No registered users and 4 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Jump to:  
cron
Powered by phpBB® Forum Software © phpBB Group