.NET Forum / Languages / C# / December 2005
Volatile fields
|
|
Thread rating:  |
yaron - 12 Dec 2005 08:26 GMT Hi all,
let be focus on sigle processor machine 32 bits. 1. with multi-threaded on single processor machine 32bit do i have to sync access to atomic get/set properties of type less then 32 bits ? 2. for those properties is it enough to use volatile on single processor machine ? 3 does volatile solve the problem for multi-processor machine ? 4. does the problems optimizations/reordering/caching makes problems with multi-threading on single processor machine 32bit ?
Thanks all.
Scherbina Vladimir - 12 Dec 2005 08:40 GMT > Hi all, > > let be focus on sigle processor machine 32 bits. > 1. with multi-threaded on single processor machine 32bit do i > have to sync access to atomic get/set properties of type less then 32 bits > ? you should sync access to data of any type.
> 2. for those properties is it enough to use volatile on single processor > machine ? No. from msdn: "The volatile keyword is a type qualifier used to declare that an object can be modified in the program by something such as the operating system, the hardware, or a concurrently executing thread." Volatile keyword does not make your variable syncronized.
> 3 does volatile solve the problem for multi-processor machine ? No.
> 4. does the problems optimizations/reordering/caching > makes problems with multi-threading on single processor machine 32bit ? Volatile object are not used in optimization, because they can be modified at any time.
-- Vladimir
Jon Skeet [C# MVP] - 12 Dec 2005 08:49 GMT > > Hi all, > > [quoted text clipped - 4 lines] > > you should sync access to data of any type. Yes, although volatile serves that purpose.
> > 2. for those properties is it enough to use volatile on single processor > > machine ? [quoted text clipped - 3 lines] > operating system, the hardware, or a concurrently executing thread." > Volatile keyword does not make your variable syncronized. Unless I'm mistaken, you're quoting from the C/C++ documentation, which doesn't apply to C#.
> > 3 does volatile solve the problem for multi-processor machine ? > > No. It does, actually - for types for which volatile is appropriate. (See link below.)
> > 4. does the problems optimizations/reordering/caching > > makes problems with multi-threading on single processor machine 32bit ? > > Volatile object are not used in optimization, because they can be modified > at any time. It means a lot more than that. See http://www.pobox.com/~skeet/csharp/threads/volatility.shtml
Jon
yaron - 12 Dec 2005 09:37 GMT Hi Jon,
You answer on my questions on this topic before, but i didn't understand what are the conclusions on my simple example. what can be done on single processor 32 bit and what can't be done on multi-processor machine ? (i means do i must use sync on those 32 bits properties or volatile are enough ?)
Thanks a lot.
> > > Hi all, > > > [quoted text clipped - 35 lines] > > Jon Jon Skeet [C# MVP] - 12 Dec 2005 10:08 GMT > You answer on my questions on this topic before, but i didn't understand > what are the conclusions on my simple example. > what can be done on single processor 32 bit and what can't be done on > multi-processor machine ? (i means do i must use sync on those 32 bits > properties or volatile are enough ?) The CLI spec makes no mention (that I remember anyway, in the relevant section) of single or multi-processor boxes. Something is either guaranteed to work according to the spec or it isn't.
If you use volatile variables, the "read" values are guaranteed to be the most recent "written" values, and you'll never see "half" a write (i.e. it's atomic as well as volatile).
Note that making a reference type variable volatile only makes that variable's value - i.e. the reference - volatile. Changing the value of the data in the object the reference refers to doesn't come into the volatility.
Personally, I tend to use locks for all shared data. I would only use volatile for predefined value types of 32 bits or less - int, bool, char etc. It should work fine for those, however.
Jon
Abubakar - 12 Dec 2005 11:09 GMT Hi Jon,
> > > 2. for those properties is it enough to use volatile on single processor > > > machine ? [quoted text clipped - 6 lines] > Unless I'm mistaken, you're quoting from the C/C++ documentation, which > doesn't apply to C#. I just checked the C# Programmer's Reference, and it quotes what Vladimir posted. The link is: http://winfx.msdn.microsoft.com/library/default.asp?url=/library/en-us/dv_csref/ html/78089bc7-7b38-4cfd-9e49-87ac036af009.asp msdn : "The volatile keyword indicates that a field can be modified in the program by something such as the operating system, the hardware, or a concurrently executing thread."
and also: "The volatile modifier is usually used for a field that is accessed by multiple threads without using the lock statement to serialize access. Using the volatile modifier ensures that one thread retrieves the most up-to-date value written by another thread.", which is what u also have mentioned.
-Ab. http://joehacker.blogspot.com
> > > Hi all, > > > [quoted text clipped - 35 lines] > > Jon Jon Skeet [C# MVP] - 12 Dec 2005 11:30 GMT > > > No. from msdn: "The volatile keyword is a type qualifier used to declare > > > that an object can be modified in the program by something such as the [quoted text clipped - 6 lines] > I just checked the C# Programmer's Reference, and it quotes what Vladimir > posted. Well, nearly - not exactly. The phrase "type qualifier" never appears, for instance.
> The link is: <snip>
> msdn : "The volatile keyword indicates that a field can be modified in the > program by something such as the operating system, the hardware, or a > concurrently executing thread." That's unfortunate, in my view. It makes volatile fields sound too much like C/C++ volatile fields, whereas I believe the behaviour is significantly different.
> and also: "The volatile modifier is usually used for a field that is > accessed by multiple threads without using the lock statement to serialize > access. Using the volatile modifier ensures that one thread retrieves the > most up-to-date value written by another thread.", which is what u also have > mentioned. Indeed. There's more to it than that though, as it affects how *other* fields are accessed. See the previously specified link for more details.
Jon
Abubakar - 12 Dec 2005 11:36 GMT > Well, nearly - not exactly. The phrase "type qualifier" never appears, > for instance. yes I also noticed it. Thanks for the reply, I'll look into it.
Ab. http://joehacker.blogspot.com
> > > > No. from msdn: "The volatile keyword is a type qualifier used to declare > > > > that an object can be modified in the program by something such as the [quoted text clipped - 33 lines] > > Jon yaron - 12 Dec 2005 14:18 GMT Thanks Jon and Abubakar.
> > Well, nearly - not exactly. The phrase "type qualifier" never appears, > > for instance. [quoted text clipped - 49 lines] > > > > Jon Willy Denoyette [MVP] - 12 Dec 2005 15:36 GMT >> > > No. from msdn: "The volatile keyword is a type qualifier used to >> > > declare [quoted text clipped - 24 lines] > like C/C++ volatile fields, whereas I believe the behaviour is > significantly different. IMO the semantics are exactly the same, in what sense would they be different? The JIT compiler generates exactly the same native X86 instructions from the IL stream as the C compiler back-end does from the C token stream for volatile field accesses.
That means that following C# snip:
static volatile int v; int u; ..
v = 0; // other C# code statements that don't use i ... u = i;
effectively writes the value 0 to the "memory location" at the point of the assignment in the source code, and reads the same location back to store the value in u.
Note that the JIT compiler produces the following X86 stream (comments added).
xor edx, edx -> clear edx mov [0x09122446], edx -> store edx into location at address 0x09122446 (fictive address) ...// other JITed code mov eax, [0x09122446] -> load contents of volatile memory at 0x09122446 into eax mov [0x0912245a] , eax -> move value read from volatile field to location of u.
which is exactly the same as produced by the C++ back-end for the same code snip. Note here that the compilers are not allowed to: - optimize away the first store, - reuse edx to load the value into u - to move the first store until after the load of v
So following is not allowed:
...// other JITed code xor edx, edx -> clear edx mov [0x0912245a] , edx -> don't bother about i and move 0 into u mov [0x09122446], edx -> move O into v
while it's perfectly valid for optimized builds when v is not volatile.
Willy.
PS. Note that these kind of optimizations are not (yet) done b the JIT compiler.
Jon Skeet [C# MVP] - 12 Dec 2005 18:02 GMT > > That's unfortunate, in my view. It makes volatile fields sound too much > > like C/C++ volatile fields, whereas I believe the behaviour is > > significantly different. > > IMO the semantics are exactly the same, in what sense would they be > different? I expect they're the same for managed code - sorry, I wasn't clear. I think they're different than the semantics for *unmanaged* code, in that the memory model is much more explicit. In particular, I'd expect that in *some* implementations of C/C++, the volatility of one variable doesn't affect how another variable is accessed. (That's the case in Java.)
Put it this way - even if the MS compiler generates the same code, can you point to places in the C specification which indicate that the same semantics are required with respect to volatile in unmanaged C as in managed code?
 Signature Jon Skeet - <skeet@pobox.com> http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet If replying to the group, please do not mail me too
Willy Denoyette [MVP] - 12 Dec 2005 19:13 GMT >> > That's unfortunate, in my view. It makes volatile fields sound too much >> > like C/C++ volatile fields, whereas I believe the behaviour is [quoted text clipped - 14 lines] > semantics are required with respect to volatile in unmanaged C as in > managed code? While the volatile keyword is part of the C++ language, but it's semantics are platform dependant and the standard allows a compiler to ignore the keywords. But, what I refered to is MSFT's implementation as described in C/C++ documention Language Reference (MSDN). MSFT C++ compiler (VC++) Volatile semantics apply to both managed and unmanaged C++ language syntax for X86 and X64 platforms, note that the example I gave is comparing C# and native VC++ behavior.
Willy.
Jon Skeet [C# MVP] - 12 Dec 2005 20:16 GMT > > Put it this way - even if the MS compiler generates the same code, can > > you point to places in the C specification which indicate that the same [quoted text clipped - 3 lines] > are platform dependant and the standard allows a compiler to ignore the > keywords. Exactly. That was what I was trying (apparently somewhat unsuccessfully
:) to say.
> But, what I refered to is MSFT's implementation as described in C/C++ > documention Language Reference (MSDN). > MSFT C++ compiler (VC++) Volatile semantics apply to both managed and > unmanaged C++ language syntax for X86 and X64 platforms, note that the > example I gave is comparing C# and native VC++ behavior. Looking again at MSDN, it certainly talks about acquire/release semantics, but only mentions "global or static objects". Does this include global variables of primitive types, for instance? I would imagine it probably does, but I don't know enough details about C++ terminology to say for sure.
I guess what I'm really trying to say is that C/C++ programmers should really look carefully at the .NET memory model, trying to put knowledge of C/C++ memory models behind them, however similar they *may* be. I believe it's easier to learn something from scratch than to try to work out any precise differences.
 Signature Jon Skeet - <skeet@pobox.com> http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet If replying to the group, please do not mail me too
Willy Denoyette [MVP] - 12 Dec 2005 22:03 GMT >> > Put it this way - even if the MS compiler generates the same code, can >> > you point to places in the C specification which indicate that the same [quoted text clipped - 19 lines] > imagine it probably does, but I don't know enough details about C++ > terminology to say for sure. Don't know why they only mention "global or static" objects, the VC compiler also allows locals to be volatile (this is not true for C#). Yes, the same primitive types are valid as long as their size is smaller than the platforms native word size (32 bits on X86). So for C++ we have bool, (unsigned/signed) char, short, int - float, and pointer variables.
> I guess what I'm really trying to say is that C/C++ programmers should > really look carefully at the .NET memory model, trying to put knowledge > of C/C++ memory models behind them, however similar they *may* be. I > believe it's easier to learn something from scratch than to try to work > out any precise differences. Absolutely right, C++ programmers in general ignore the volatile qualifier completely, the few who use it know (or should know) the memory model and platform specifics, in general driver writers know how to use volatile.
Willy.
Free MagazinesGet these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...
|
|
|