Threading Confusion

    This site uses cookies. By continuing to browse this site, you are agreeing to our Cookie Policy.

    • Threading Confusion

      Hey Guys,

      I have been trying to understand threading and how to implement it in my engine, I tried a simple example using _beginthread and it worked good, I just had a function that altered a global variable and made multiple threads for it. I also read up on using _beginthreadex for member functions, and it does successfully call my function, but it fails after a bit. I am having trouble understanding this chapter and maybe it's just me not looking at it the right way.

      I tried to use a thread to update my physics manager, and I thought, what do I actually use the thread for? Do I initialize my physics manager normally, as well as add my rigid bodies to it normally, but my Update function should be running in a thread? What should run in threads and what shouldn't? Should I only be adding single functions to threads such as the update function of my physics manager? Should my scene synchronization be done seperately? I tried several things and they all had issues

      a). In my Physics manager's init function I made a thread that had an infinite loop calling update, I then end the thread in the shutdown

      b) I called _beginthreadex every frame (I didn't quite understand threads as much at this point)

      What am I doing wrong? I get a ton of errors with anything I try
      PC - Custom Built
      CPU: 3rd Gen. Intel i7 3770 3.4Ghz
      GPU: ATI Radeon HD 7959 3GB
      RAM: 16GB

      Laptop - Alienware M17x
      CPU: 3rd Gen. Intel i7 - Ivy Bridge
      GPU: NVIDIA GeForce GTX 660M - 2GB GDDR5
      RAM: 8GB Dual Channel DDR3 @ 1600mhz
    • RE: Threading Confusion

      Originally posted by mholley519
      I have been trying to understand threading and how to implement it in my engine, I tried a simple example using _beginthread and it worked good, I just had a function that altered a global variable and made multiple threads for it. I also read up on using _beginthreadex for member functions, and it does successfully call my function, but it fails after a bit. I am having trouble understanding this chapter and maybe it's just me not looking at it the right way.

      I'm not directly familiar with the _beginthread() API. It looks like you just pass in a function pointer, which is pretty typical of threading API's. Multi-threaded programming is tough. You have to think in a very different way and the debugging tools aren't usually great. Are you running this under Visual Studio? If so, there's a Threads tab in the debugger that will show you all the running threads and where they are. That can be helpful to figure out what's wrong.


      I tried to use a thread to update my physics manager, and I thought, what do I actually use the thread for? Do I initialize my physics manager normally, as well as add my rigid bodies to it normally, but my Update function should be running in a thread? What should run in threads and what shouldn't? Should I only be adding single functions to threads such as the update function of my physics manager? Should my scene synchronization be done seperately? I tried several things and they all had issues

      In the old days, threads did very little except conceptually break out paths of execution. These days, your average processor has at least 2 cores and often 4 or more. Each core can run a different thread simultaneously, so in the most optimal case, you can do twice the work in a single frame. That's really powerful. A good multi-threaded game will run 2 - 3 times faster while a poorly implemented multi-threaded system will be unstable and actually run slower. I worked on an engine a few years back where they were locking the main & render threads for each render call, which meant it would be locked dozens if not hundreds of times a frame. This actually made the game slower than if they just implemented it in a single-threaded system.

      The best candidates for threading are self-contained systems with very few access points that are bottlenecks, especially if those bottlenecks aren't CPU dependent.

      In my own game engine, I have three threads. One is the main thread and it runs the core game logic. This is where most of my code lives.

      The second is my render thread, which does the actual rendering of my scene. This is a good candidate because there's only one interface into my render system: AddObjectToScene(). This function adds an object to a draw list that gets copied over to the render thread during the synchronization phase of my frame. It's also a big bottleneck. In the single-threaded version of my game, 90% of my frame time was taken up by the D3D Present() function rendering the scene. My CPU is pretty much idle during that time as the video card churns away. Having this on another thread lets the OS redistribute those CPU cycles to my logic side.

      The third thread is my resource loader. Again, I have a very simple interface in the form of a queue. When a new item is added to it, it wakes up the loader thread, copies everything over, and lets the loader thread go to work. As things get loaded, the main thread gets notified. When the loader thread is done, it goes back to sleep. This is a great place for a thread because I have an open world that streams off the hard drive. In single-threaded mode, I get a hitch every few seconds as I walk around the world because the game has to wait for new assets to be loaded. In multi-threaded mode, there's no hitch at all, although I hear the hard drive "tick" every few seconds.

      Physics is a common thing to toss on another thread, though it's usually harder than something like a resource loader simply because there are so many hooks into the physics system. A poor implementation could cause a lock for every physical object in your game as it tried to update the position of the entity.


      a). In my Physics manager's init function I made a thread that had an infinite loop calling update, I then end the thread in the shutdown

      My threads work similarly. I have a class that acts as the main-thread interface. It's in charge of spinning up the new thread on initialization and tearing it down again during shutdown. The thread function itself depends on the purpose of the thread. My render thread is effectively an infinite loop. When it spins up, it immediately waits for an event. When I'm ready to start rendering, I send a RUN event, which causes it to render whatever it has in its queue. The main thread processes at the same time, adding things to a different queue. When the render thread is done, it triggers an end-of-frame event and goes to sleep. Meanwhile, the main thread does its thing. At the end of its processing, it goes to sleep and waits for that end-of-frame event (it won't sleep if the render thread finishes first). Once the end-of-frame event has occurred and the logic thread is done, the frame enters the synchronization point. At this point, the render thread is asleep and the logic thread can safely make changes. It swaps the two queues (this is done by changing a single index value, so it's very fast), then sends the Run event to the render thread. That ends the synchronization point and they both continue.

      The idea is that both the main thread and the render thread process a single frame at a time, then faster one waits for the slower one. The render thread is always rendering one frame behind what the main thread is building up. Both threads are always in synch and they will always run at a speed equal to the slowest of the two. So if my render thread takes 20ms and my main thread takes 15ms, my frame will be 20ms long. This is much better than a single-threaded system, which would take 35ms in that case.

      My loader thread works a bit differently, though the concept is the same. Instead of looping forever, it goes to sleep whenever it's done processing the queue. You never want a thread to do this:

      Source Code

      1. // wait for data
      2. while (someList.empty());


      The above loop looks like a LOT of work from a CPU's point of view. If you put the thread to sleep instead, the CPU ignores it completely.


      b) I called _beginthreadex every frame (I didn't quite understand threads as much at this point)

      Ouch. That'll create a new thread every frame. I'm guessing this crashed.


      What am I doing wrong? I get a ton of errors with anything I try

      I'm not really sure since it's not clear what specific errors you're running into. One thing that helps is to isolate the specific thing you're trying to do into a simple test (maybe even outside of your engine) just so you can remove all the extra stuff. If you have an isolated chunk of code you can show me, that would help too. Also, any explanation as to the specific issues you're getting would help.

      -Rez