Monday, August 26, 2013

Multithreaded rendering

This time more technical but I think it's really interesting stuff for some of you :]

More than week ago I created new branch on my git repository containing code for "multithreaded rendering". Problem like this are never easy and in my case I needed to deal with OpenGL. And for this who don't know OpenGL is state machine and because of this isn't parallel friendly. All creation of resources, uploads of data, rendering and releasing of it need to be done on the same thread where context were created.

So you see a lot of restriction which complicate already not easy problem. Personaly I thought about solution of it from some time already but couldn't found any that would fit my needs. In most cases there were problems how nicely fit it into my architecture, how to deal with synchronization and few other stuff. But not so long ago I found at last way to deal with it and of course didn't started to code it

In last few years I learned that if we have any idea and we want to realize it, then there is need to give it some time. Start doing something else, talk with people that can give some tips or comments, search for weakness of solution and if we have time wait even week or two. If after everything this idea is still there there is big possibility that it's really worth work that we will put in it. In other way we would lost time reverting changes or dealing with incomplete creation that will need a lot of tweaks later .

So after month of thinking I decided to begin work. I split task from my main thread on few others and right now my threads look like that:
  • Main Thread :
    • Upload loaded data to GPU
    • Rendering using OpenGL api.
  • IO thread :
    • Process inputs from devices  (mouse, keyboard, pads, oculus rift).
  • Game Thread :
    • Physics update
    • Process game logic
    • Prepare scene to rendering
    • Loading data to memory (from i.e. disk)
  • Working threads
    • Execution of jobs
Everything proceed with replacing step by step elements of current pipeline with new one. I done it that way so I could check if any change don't brake anything. In meantime I needed to deal with some problems about which I though a lot ( i.e. how exchange information about what to render between threads ) and this which I didn't thought so much ( i.e. synchronizations between loading of data to OpenGL and using it in rendering ). 

Right now it's really hard to tell how big performance gain will be from this changes but I can say for sure that there is a lot of problems like crashes and bugs that I still need to deal with. But as John Carmack wrote on his twitter: 
"Many types of performance optimization screw up your codebase, but making functions pure for parallel execute actually improves it."
I can say that after all this changes my code starting to be a lot cleaner, stable and I could even say a lot easier to understand.

Till the next post.

No comments:

Post a Comment