Orderly Mayhem
May 21, 2012, 03:01:47 PM *
Welcome, Guest. Please login or register.

Login with username, password and session length
News:
 
   Home   Help Search Contact Staff List Login Register  
Pages: [1]   Go Down
  Print  
Author Topic: Argh! Multithreading woes!  (Read 1406 times)
BS-er
Moderator of Mayhem
Administrator
*****
Offline Offline

Posts: 2150


View Profile
« on: May 19, 2007, 03:41:41 PM »

We've release version 0.01 to the testers, and in doing so I asked them to have their dual-core machines chew on it with the two threads enabled.  I've always heard its a good idea to test multithreaded apps on dual-cores and now I see why.  It seems to run worse than it does on a single core, with stuttering and some crashes.  I think I'll need to break down and get a dual core machine eventually so that I can debug on it. 
Logged
AcneVulgaris
Full Member
***
Offline Offline

Posts: 120


View Profile
« Reply #1 on: May 26, 2007, 12:28:29 PM »

How have you brokent things out into threads?  AI/Everything else?
Logged
BS-er
Moderator of Mayhem
Administrator
*****
Offline Offline

Posts: 2150


View Profile
« Reply #2 on: May 27, 2007, 10:05:34 AM »

I've broken it up so that graphics can run in one thread, and the world updates can run in another.  World updating is all physics, AI and all that.  Actually particle physics happen in the graphics thread because that's tied to the Ogre graphics engine.  So basically one thread is for Ogre, and one for the world stuff that I design.  If only one thread is chosen, then its all called from the same loop.

The world and the graphics are very decoupled (or s I hope).  A lock must occur prior to each new world update to transfer new position and orientation for each movable object.
Posted on: May 27, 2007, 08:57:51 AM
Efficiency in that process is gained because this transfer is needed only for movable objects in VISIBLE range, which shouldn't be a whole lot.
Logged
AcneVulgaris
Full Member
***
Offline Offline

Posts: 120


View Profile
« Reply #3 on: May 27, 2007, 03:13:09 PM »

I would imagine that the locking is causing a lot of stall conditions as the cores try to get out of each others way.  Sounds like it could get crazy complex to optimize.  Is the windows process scheduler smart enough to fob any work off to multiple cores if you run as a single thread?

Maybe you could do some kind of global state dupication/locking, where the physics thread is updating the next world state while the graphics thread is drawing the current one...then you could switch states with pointers.  That way you'd only have to deal with one big fat lock and could keep your cores somewhat busy.

Logged
Red Devil
Newbie
*
Offline Offline

Posts: 38


View Profile
« Reply #4 on: May 27, 2007, 10:52:25 PM »

Aegeis support?
Logged
OvermindDL1
Casual Support Developers
*
Offline Offline

Gender: Male
Posts: 278

Programmer


View Profile WWW
« Reply #5 on: May 28, 2007, 03:34:36 AM »

I've always heard its a good idea to test multithreaded apps on dual-cores and now I see why.
Reason of course being that multiple threads on a single core are pretty useless/detrimental except for I/O locking. Smiley

Quote
/* last two posts */
That... sounds very inefficient.  I would recommend the pattern I talked about earlier (don't recall which forum, this was quite some time ago) using a non-locking pattern.  I used a combination of message passing and volitale memory.  I set it up so a variable is only ever written to by one thread, but may be read by many (except in a few cases, also described here).  For example, an actor class has a number of parts, a physics body, a graphical body, input (by player or AI or what-not).  It worked in a simplified manner of when an input was received then all listener's of a certain input event (I have a nice binding system so there can be any number of virtual 'keys' (up, down, jump, rotate_up, etc... etc...) that can be added at any point, and were bound to any number of other virtual keys.  Real keys always called a certain named virtual key (so the up key called the virtual key key_up, and w did key_w and so forth.  The variable was a floating point number bound between 0 and 1.  Keyboard keys, mice buttons, joystick buttons, mouse axis, joystick axis, etc... etc... always mapped to a certain virtual key, axis were done so each direction went to a different one such as joy0_0_pos, joy0_0_neg, joy0_1_pos, etc..., always bound between 0 and 1, so pushing up or down on something could do different things, and you could even put in a filter to bind it between something, so it only called listeners if it went between like 0.2 and 0.38 or whatever when bound to a different key (when a virtual key was bound to another virtual key, a filter could be passed in).  When an input was called though, and a listener received the event and acted on it, say the key was 'key_w', which called 'forward_0', which called the listener bound inside the player controller 0's callback 'forward', which then called the attached actor's 'forward' callback, which set a volitale variable atomically to its value plus the craft's forward rate (say 80.0).  By atomically I mean that the variable fit into a register, and I could do an atomic CAS to set it, if other things were trying to set at the same time, then they would all succeed in the proper way.  When the physics thread came by and reads that value atomically (atomically because the full value will not fit into a register, and if it was not then different axis could be wrong if something was writing to it as well), applies the proper forces, etc.. atomically reads and sets the value at a minus of what it read before (in case something wrote to it while the physics forces were being calculated on it).  When the physics finishes calculating a world step and it calls a callback on the bodies to tell them of their updated position and orientation, that callback would send a message to the graphics thread that when it goes through its messages (once per frame), it would see that the body says its position is updated, so the graphics thread would then atomically read the new position and orientation, updates the graphical body, and continues on.  The AI of the AIControllers that control actors would do what they can during an update, making sure they are thread-safe of course (meaning using atomic primitives when possible, not locks), and just put them in an atomic circular queue so when any thread has any spare time then it can pull the next task off and run it.  With enough of the system running as those 'tasks' in small enough timeslices (not too small though), then it could scale exceedingly well with many cores, where-as the above posted method does not.
Logged

BS-er
Moderator of Mayhem
Administrator
*****
Offline Offline

Posts: 2150


View Profile
« Reply #6 on: May 28, 2007, 07:53:29 PM »

I must admit I'm a much better engineer than I am a programmer or software designer.  My engineering background has lended itself well to the physics and AI (which I had to dumb down drastically, combat-wise, just as Lizard Smiley).  I'm a decent C++ programmer but I find that I must drive on and "just do it" when it comes to the programming.  However that is working for me quite well actually.

Even if the locking is a bit inefficient, it will involve the transfer of a vector and quaternion per unit in range, 15 times per second.  Its reasonable to think 50 to 75 units are in visible range, given the planned scope.  I would bet that switching to your concept would have no perceptable impact, even if efficiency is increased.

Whe I decided not to try and be a demi-god programmer, my progress went through the roof, and the code ain't so bad I think.  Maintainable by me at least.

Still, your approach is something to think about.  It is desirable to minimize or avoid locking.
Logged
OvermindDL1
Casual Support Developers
*
Offline Offline

Gender: Male
Posts: 278

Programmer


View Profile WWW
« Reply #7 on: May 28, 2007, 09:03:26 PM »

I made a couple engines using a few different multi-threading approaches, it seemed to be the most efficient and scalable.  And the locking would not be really inefficient if there are no contests, but if the physics tries to update positions, while graphics just starts reading them, that could be a sizable enough down-time with locks...
I personally just do not like locks, too easy to miss too many things that could cause 'bad things', whereas with a non-locking method, as above, it reduces the possabilities to near nothing, and the calls themselves are at most 12ticks long, usually less (amd systems are 4ticks as I recall, most intel's are 11ticks), less then most locking primitivies short of a short-timed critical section, which is the exact same amount of ticks.  If there is a contention, meaning that they try to access the same memory at the same time, which should never really happen, then it jumps up to at most about 220ticks, still shorter then any lock contention.  You just have to slightly change the way you program those.

The main reason I tried to come up with a method that is finely grained and can scale near infinitally was for making a world with quite a bit of a few more then 100 units.  Remember, I am a strategy player, not an fps player, I really do not like fps', but I like strategy with thousands upon thousands of units, I am an old TA player after all, and this method scales exceedingly well with pathfinding calculations and ai with all those units. Smiley

I do want a game like BZ2, but I want it so I can be in the 'super-destroyer' sending out hundreds of wings of fighters out of my docking bays to batter down an enemy of proportional strength...  I do not like these little raiding party type of things, I like numbers, I played the Zerg in Starcraft, not the Protoss...  (Although the Mantis in that one other space strategy game is probably a better comparison.)
« Last Edit: May 28, 2007, 09:08:15 PM by OvermindDL1 » Logged

Avatar
Casual Support Developers
*
Offline Offline

Posts: 88


View Profile
« Reply #8 on: June 06, 2007, 08:18:14 PM »

... to the physics and AI (which I had to dumb down drastically, combat-wise, just as Lizard )...

 Huh

 Shocked

You did WHAT to Lizard???

 Grin

-Av-
Logged
BS-er
Moderator of Mayhem
Administrator
*****
Offline Offline

Posts: 2150


View Profile
« Reply #9 on: June 06, 2007, 09:40:51 PM »

Heh I never noticed that typo.  Should be "Just Ask Lizard".  That's my story and I'm sticking to it Smiley.
Logged
Pages: [1]   Go Up
  Print  
 
Jump to:  

Powered by MySQL Powered by PHP Powered by SMF 1.1 RC3 | SMF © 2001-2006, Lewis Media Valid XHTML 1.0! Valid CSS!


Google visited last this page May 15, 2012, 09:15:45 AM