Game Development Reference
In-Depth Information
'
then overwritten by the next thread
s CPU registers, and the CPU begins to run the
code for the new thread. This leads to some interesting behaviors if multiple threads
manipulate the same bit of memory. Take a look at the assembly for incrementing a
global integer:
++g_ProtectedTotal;
006D2765 mov eax,dword ptr [g_ProtectedTotal (9B6E48h)]
006D276A add eax,1
006D276D mov dword ptr [g_ProtectedTotal (9B6E48h)],eax
There are three instructions. The first loads the current value of the variable from
main memory into eax , one of the general purpose registers. The second increments
the register, and the third stores the new value back into memory. Remember that
each thread has full access to the memory pointed to by g_ProtectedTotal , but
its copy of eax is unique. A thread switch can happen after each assembler level
instruction completes.
If a dozen or so threads were running these three instructions simultaneously, it
wouldn
t be long before a switch would happen right after the add instruction but
before the results were stored back to main memory.
In my own experiments, the results were pretty sobering: 20 threads each increment-
ing the variable 100,000 times created an end result of 902,149. This means 1,097,851
additions were completely missed. I ran this experiment on a Windows 64-bit system
equipped with an Intel Core i7-2600 CPU.
Lucky for you and everyone else out there wanting to take full advantage of their
CPUs, there are ways to solve this problem. But first, you should know how you cre-
ate the thread in the first place.
'
Creating Threads
Under Windows, you use the CreateThread() API. For you programmers who
desire a more portable solution, you can also choose the _beginthread() call or
the threading calls in the Boost C++ library.
DWORD g_maxLoops = 20;
// shouldn't be on a stack!
DWORD g_UnprotectedTotal = 0;
// the variable we want to increment
DWORD WINAPI ThreadProc( LPVOID lpParam )
{
DWORD maxLoops = *static_cast<DWORD *>(lpParam);
DWORD dwCount = 0;
while( dwCount < maxLoops )
{
 
 
Search WWH ::




Custom Search