Neat article at gamasutra about multithreaded architectures

Meh, can't edit post. If a mod could please change the title to read:

"Neat article at Gamasutra about multithreaded architectures"
 
It's not so much an article about multithreaded architectures but instead an introduction to thread synchronisation and protecting shared resources. The real difficulty with multithreadeding is designing an architecure where you can keep more than one thread busy without sacrificing too much efficiency.

GP.
 
No, it is not a mutex. It is an atomic update. The whole point is to have a lock-free algorithm. Many CPU architectures provide instructions to do this, like compare-and-swap or load-linked/store-conditional or load-and-reserve. It's different on each architecture. Some architectures even have a double-CAS which allows atomic updates or larger values.

I don't particularly like Microsoft's terminology. Traditionally, the terminology has been "atomic" such as "atomic integer", "atomic float", etc. For example, OpenMP and Java's Concurrent utilities both use this terminology. MS's documentation in this area particularly stinks. java.util.concurrent.AtomicInteger provides a much better description of how this is implemented.


Atomic operations *may* be converted into critical sections, but the whole point is to avoid this scenario on architectures that can support atomic update/increment/decemebet/add/swap/etc more efficiently.

BTW, the article leaves out a TON of interesting concurrency primitives. In addition to mutexes and critical sections, the following are highly useful:

condition variables
read/write locks
counting semaphores
"fair" vs "unfair" critical sections
latches and barriers

plus

lock-free versions of queues, maps, lists
blocking queues and exchangers


Besides which, it says nothing about dealing with serialization of memory writes.
 
Last edited by a moderator:
Question: Is this multiprocessor safe?

int iValue;
BOOL fValueHasBeenComputed = FALSE;

int ComputeValue(void)
{
int value
value = 128*7+4;
fValueHasBeenComputed = TRUE;
return value;
}

void CacheComputedValue()
{
if (!fValueHasBeenComputed)
{
iValue = ComputeValue();
}
}

BOOL FetchComputedValue(int *piResult)
{
if (fValueHasBeenComputed)
{
*piResult = iValue;
return TRUE;
}
else
return FALSE;
}
 
You may end up computing it N times where N is the number of processors, in the most extremely unlucky case :)

Also, if iValue is more complex and some parts of it are written twice, you will sooner or later end up with corrupt data.
 
Last edited by a moderator:
Back
Top