Re: mutex question
- From: "Tom Widmer [VC++ MVP]" <tom_usenet@xxxxxxxxxxx>
- Date: Wed, 03 May 2006 17:34:41 +0100
David Jones wrote:
Stealer wrote:
// ???? while(x); <> while(x) { statements} ???
// VC Compiler bug in Release configuration
[...snip...]
continue_flag = 1;
CreateThread(NULL, 0, ThreadProc, 0, 0, 0);
while (continue_flag)
{
//printf("You : I love you, Bill\n"); // you can not exit this program
if remove this line.
};
[...snip...]
// Note: You must buid in Release to find out the problem
// Disassembly:
// 00401048 jmp 00401048
// --> no compare before jmp
This is not a compiler bug -- this is a code bug. The continue_flag
variable should be declared as volatile since it can be modified by
another thread. Since you're not changing continue_flag in the loop,
it is perfectly valid for the compiler to optimize the check away
completely.
That's true.
This is why the 'volatile' keyword exists -- to tell the compiler
that a variable can change unexpectedly, such as when it is shared
between threads. Today's compilers are smart, but they can't read
your mind (yet). :)
That is *not* what volatile is for - multithreading is not part of its utility, rather hardware interaction is.
Why does it not optimize the check away when a call to printf is in
the loop? Maybe since it's a global variable and you're calling a
function in another compilation unit, it thinks that the variable
might be extern'ed and potentially modified by that function. I'd
bet that if you replaced the statement with, say, setting the value
of a local variable, you'd get the optimized code -- just jmp. (It
would probably move the assignment out of the loop.)
Long story short: use 'volatile' on variables shared between threads.
On the contrary, it is *not* necessary nor is it sufficient to use volatile on variables shared between threads. Instead, use the Interlocked* operations, the new memory barrier calls and the synchronization primitives. Volatile doesn't cause cache synchronization between CPUs, so it is possible for two apparently simultaneous reads by different CPUs to get different values (though this doesn't apply to x86 multiprocessor, only to Itanium and PowerPC AFAIK). Memory barriers (and the operations that emit them, such as EnterCriticalSection, WaitForSingleObject and InterlockedCompareExchange), not volatile, are the correct mechanism to force updating of variables between threads. If you use memory barriers, volatile doesn't help, and if you don't use memory barriers, volatile won't work on all platforms, so it is neither necessary nor sufficient to use it.
There's a paper on it here:
http://www.aristeia.com/Papers/DDJ_Jul_Aug_2004_revised.pdf
Alternatively, google groups will have lots of posts about this.
Tom
.
- Follow-Ups:
- Re: mutex question
- From: Slava M. Usov
- Re: mutex question
- References:
- Re: mutex question
- From: David Jones
- Re: mutex question
- Prev by Date: Re: strange performance behaviour for memcpy in 64 bit app
- Next by Date: x64 and the registry hives and 32-bit compatibity
- Previous by thread: Re: mutex question
- Next by thread: Re: mutex question
- Index(es):
Relevant Pages
|
Loading