Threading tutorials

Oldtimer
Posts: 834
Joined: 2002.09
Post: #1
Does anyone know of any good tutorials/articles on getting started with threading? Preferrably boost::threads, but seeing as the supply is scarce on it, pthreads would be just fine. (Or whatever threading lib you might've found.)
Quote this message in a reply
Luminary
Posts: 5,143
Joined: 2002.04
Post: #2
Threading itself is remarkably simple -- all the APIs are pretty much the same. You get some way to call a function in a new thread, and some synchronization APIs, the details which can differ significantly depending on which threading API you use, but ultimately perform the same task.

The crucial thing to make sure you understand is why this function is buggy:

Code:
int x = 0;

void add_one_to_x()
{
    ++x;
}

Once you understand that, the rest is basically API details.
Quote this message in a reply
Oldtimer
Posts: 834
Joined: 2002.09
Post: #3
Well, if you say so. Smile I'll start with pthreads then, and move to boost when I feel I can handle posix. As to why the function is buggy, idk... because the data is shared between threads and I can't trust x to be incremented by one by calling it? It might be incremented from any number of threads, right under my nose?
Quote this message in a reply
Puzzler183
Unregistered
 
Post: #4
x isn't volatile, therefore the value in it could be wrong?
Quote this message in a reply
Sage
Posts: 1,199
Joined: 2004.10
Post: #5
This brings up a big question for me. I downloaded OSC's threaded-newton demo, hoping to glean some useful info. But it seemed... a little short on documentation as to how it works. If I recall, I didn't see any comments, really, and no overview of what it's doing.

I could spend a couple hours figuring out what it's doing, but I might as well ask the author: OSC -- what's it doing? What's the principle of its operation?

Now, that said, I've contemplated this for my own work. My game currently is multithreaded, but in a synchronous manner. E.g., the physics thread runs while the drawing thread blocks for VBL sync. So, really, it's only multithreaded in name, not behavior. Also, I'm not using Newton, I'm using ODE. So what works for Newton may not be applicable elsewhere -- I don't know, since I don't know anything about newton other than that it looks like it ROCKS.

The way I see a generic multithreaded display & physics system working, is this: An object which is to have physics ( and other game logic ) run in one thread, and drawn in another, has to have a sort of contract, that the physics thread provides certain info for the drawing thread. Producer, consumer. Info like position, rotation, and or color or whatever, I'll call that "state". The drawing thread simply represents the object with the state the physics thread provides.

I would have each object in the game have two state objects, lets call them primary and secondary, primary has a mutex lock on it. The physics/state thread runs constantly of course and locks the mutex on the primary state, updates it, and unlocks it. The drawing thread first attempts to get a lock on the primary state to display the object with the most recent state. If it succeeds, it draws the object with that state and then copies the state to the secondary state (which the physics thread never touches). Then it unlocks the primary state. If it can't get a lock on the primary state, it just draws whatever was in the secondary state, even though it will be a little stale.

Obviously, there would need to be a first-pass situation where the physics thread locks both states and copies the first to the second, once. And there might be need to, say, every half second or so, require the drawing thread to block on gaining the primary state so it can be sure to have a not-too-stale fallback state.

But, anyway, is this dumb, or is it particularly inefficient? What do people here say? I've never attempted this, and I'm up for some constructive criticism of my approach.
Quote this message in a reply
Luminary
Posts: 5,143
Joined: 2002.04
Post: #6
Puzzler183, yes, the addition of volatile would be an improvement. However, the function would still be buggy.

Here's the assembler output from that function:

Code:
_add_one_to_x:
00000000        mfspr   r0,lr
00000004        bcl     20,31,0x8
00000008        mfspr   r10,lr
0000000c        mtspr   lr,r0
00000010        addis   r9,r10,ha16(_x-0x8)
00000014        lwz     r2,lo16(_x-0x8)(r9)
00000018        addi    r2,r2,0x1
0000001c        stw     r2,lo16(_x-0x8)(r9)
00000020        blr

Most of it's function prologue and epilogue, these three instructions do the grunt-work of the function:

Code:
00000014        lwz     r2,lo16(_x-0x8)(r9)
00000018        addi    r2,r2,0x1
0000001c        stw     r2,lo16(_x-0x8)(r9)

lwz loads a value from memory into a register (r2, from x, in this case)
addi adds an "immediate" (stored-in-the-instruction) value to a value in a register (1, to r2, putting the result in r2)
stw stores a value from a register into memory (r2, into x)

Now, there's nothing at all wrong with this without threading, or if you're careful to make sure that two threads don't call add_one_to_x simultaneously, but if they do, there are possible orderings of the ASM instructions that cause the wrong thing to happen, for example

Code:
thread 1: lwz (x == 0, r2 == 0)
thread 1: addi (x == 0, r2 == 1)
thread 2: lwz (x == 0, r2 == 0)
thread 2: addi (x == 0, r2 == 1)
thread 2: stw (x == 1, r2 == 1)
thread 1: stw (x == 1, r2 == 1)

add_one_to_x has been executed once in each thread, and the value of x has only been incremented by 1.
Quote this message in a reply
Luminary
Posts: 5,143
Joined: 2002.04
Post: #7
TomorrowPlusX, I believe that what you describe will still force the two threads to run at the same framerate, and you'll waste a lot of time waiting for the slower thread to relinquish its lock on one of the two buffers. Also, mutexes are very heavyweight objects, and you can easily lose all the benefits of multithreading to the overheads of synchronization if you're not careful. I'll describe how the Newton demo works in its thread (http://www.idevgames.com/forum/showthread.php?t=8968)
Quote this message in a reply
Sage
Posts: 1,199
Joined: 2004.10
Post: #8
Thanks, OSC. I'll read your writeup.
Quote this message in a reply
Post Reply