use of volatile keyword

A

Assaf

hi all

i know that i should not cross-post,
but i am not sure to which group to post this question.


2 quesions about volatile:

1. i use volatile when 2 threads access the same variable
is this the proper use of volatile?

2. when declaring a variable of type long, i get a compilation error
cannot use volatile with long!
does this mean that all long's are automatically volatile?
i am assuming that since they are 64 bit, the compiler will never place
them in the CPU.

any help or thoughts is very much appreciated.

assaf
 
S

Stoitcho Goutsev \(100\) [C# MVP]

Hi Assaf,
I take it you use c#.
1. i use volatile when 2 threads access the same variable
is this the proper use of volatile?
Yes, this is one of the places where *volatile* modifier is used. However
you are not expecting to have thread safety by using *volatile* only, aren't
you. Even with volatile you will have access to shared resource so locks or
other sync techniques should be used.
2. when declaring a variable of type long, i get a compilation error
cannot use volatile with long!
does this mean that all long's are automatically volatile?
i am assuming that since they are 64 bit, the compiler will never place
them in the CPU.


I couldn't find any info why *long* variables cannot be *volatile* and I
believe they are not rather than they are always.
For one variable to be volatile is not enough not to be cached int the CPU
registers. It affect optimization done by the c# compiler and JIT compiler.

HTH
B\rgds
100

news:[email protected]...
 
H

Hilton

Stoitcho said:
Hi Assaf,
I take it you use c#.

Yes, this is one of the places where *volatile* modifier is used. However
you are not expecting to have thread safety by using *volatile* only, aren't
you. Even with volatile you will have access to shared resource so locks or
other sync techniques should be used.

Volatile used to cause a build error in the CF. Make it actually compiles
before you think things through too much.

I couldn't find any info why *long* variables cannot be *volatile* and I
believe they are not rather than they are always.

Probably because loading/storing a long is not an atomic operation and
therfore isn't safe.

Hilton
 
M

Miha Markic [MVP C#]

Probably because loading/storing a long is not an atomic operation and
therfore isn't safe.

Yes, it volatile is useful only for atomic types which (64bit integer
certainly isn't).
 
A

Assaf

hi

1. why is volatile usefull for atomic types only?
2. what is your statement based on?
3. 64 bit not atomic - is that not cpu dependant?
4. so do you mean that 'long' is _always_ 'volatile'?

assaf
 
M

Miha Markic [MVP C#]

Hi Assaf,

Assaf said:
hi

1. why is volatile usefull for atomic types only?

AFAIK volatile is used when you read/write from a variable that is not
synchronized via any synchronization method.
Writing and reading to an integer (where size is equal or less then CPU
bytes) is an atomic operation and doesn't need to be synchronized.
However, if you are practising this on dual or more processor machines the
processors can have different variable versions in their cache.
Here comes volatile keyword into play. It forces processors to look at the
same variable.
Using volatile for complex types (or non-atomic) doesn't make sense since
you will always need to synchronize access to them.
2. what is your statement based on?

10.4.3 Volatile fields
3. 64 bit not atomic - is that not cpu dependant?

It is.
4. so do you mean that 'long' is _always_ 'volatile'?

No. It means that can't be volatile because you have to sync access.
 
J

Jerry III

volatile will not help you use variables without synchronization. If you'd
run your code on multiple CPUs writing into a volatile variable will not
necessarily update that memory location in all CPUs that cached it. That
only happens when you use synchronization code (locks, interlocked access
and so on). So be careful, especially if you test on a single CPU machine
and it seems to work.

Jerry
 
A

Assaf

hi jerry.

your statement is in DIRECT CONTRADICTION to the docs.

(but what do i know?
im just a programmer)

assaf
 
J

Jon Skeet [C# MVP]

Jerry III said:
volatile will not help you use variables without synchronization. If you'd
run your code on multiple CPUs writing into a volatile variable will not
necessarily update that memory location in all CPUs that cached it. That
only happens when you use synchronization code (locks, interlocked access
and so on). So be careful, especially if you test on a single CPU machine
and it seems to work.

Actually, the whole point of volatile variables is that they *won't* be
cached. See section 12.6.7 (IIRC) from partition I of the ECMA spec.
 
A

Assaf

hi all.

i'm sorry for opening a new sub-branch.
but,
could someone please tell me what to assume?
long is volatile by default?
yes or no?

assaf
 
J

Jerry III

You're right (and so is Assaf). I'm not sure what I was thinking when I
wrote that...

Jerry
 
J

Jon Skeet [C# MVP]

Assaf said:
could someone please tell me what to assume?
long is volatile by default?
yes or no?

No, long is not volatile by default. You'll need to take out a specific
lock in order to handle the data correctly - which is the general case,
to be honest. (You can, however, use the Interlocked class with longs.)
 
A

Assaf

hi jon

i am a little confused about lock vs. volatile.
as far as i understand,
there is no corelation between the two concepts!

why do people keep refering to 'locking'
when i am talking about 'caching' (volatile)?

i just took a look at the Interlocked class that you mentioned,
and there is no mention there that the variable will not be cached!

in any case,
as to your statement:
'No, long is not volatile by default'
what do you base it on?

if it is not volatile,
it might be cached,
in which case, i'll solve it,
but not by means of a lock,
unless the compiler is smart not to cached variables
accessed in locked sections

(which i doubt it does,
it would certainly degrade performatnce
not to use caching for all variables
in locked sections)

assaf
 
J

Jon Skeet [C# MVP]

Assaf said:
i am a little confused about lock vs. volatile.
as far as i understand,
there is no corelation between the two concepts!

Yes there is. Taking out a lock involves a memory barrier, as does
releasing a lock. In effect, so long as your "reading" and "writing"
sections of code both take out locks on the same reference, you get
volatile behaviour. I suggest you read the CLR spec's memory model.
Note that the reference to be locked is automatically treated as
volatile for the purposes of locking.
why do people keep refering to 'locking'
when i am talking about 'caching' (volatile)?

Because they're intimately related.
i just took a look at the Interlocked class that you mentioned,
and there is no mention there that the variable will not be cached!

The whole point of the Interlocked class is to make things thread-safe
- it does "the right thing". However, it's really only useful when
you're incrementing/decrementing/exchanging values, not just reading
them.
in any case,
as to your statement:
'No, long is not volatile by default'
what do you base it on?

The fact that nothing is volatile by default - why would it be?
if it is not volatile, it might be cached, in which case, i'll solve
it, but not by means of a lock, unless the compiler is smart not to
cached variables accessed in locked sections

So how would you solve it without a lock?
(which i doubt it does, it would certainly degrade performatnce not
to use caching for all variables in locked sections)

Hopefully once you've read the spec you'll understand how it works.
 
A

Assaf

hi jon.

concerning your statement:
'I suggest you read the CLR spec's memory model.'
could you please give me a link to the spec?
if it comes with visual studio, than just tell me the file name.

tnx

assaf
 
J

Jerry III

If you use a lock the compiler might still "cache" (I really have no idea
what you mean by that as compiler doesn't cache anything, the CPU caches the
memory - maybe you're talking about optimizations where the compiler decides
not to fetch the variable from the memory but rather uses a register value
left over from some previous computing) but the CPU cache will be refreshed
every time you use a locking function (such as when you acquire/release a
lock) or when you use an interlocked function. For details you should read
the documentation, Win32 API docs is very detailed about this (and it's
generic enough so it doesn't really apply to Win32 API only but to any code
running on pretty much any CPU, even though the implementation details vary
by CPU). I suggest you start here:
http://msdn.microsoft.com/library/en-us/dllproc/base/synchronization.asp -
the About Synchronization section is really useful.

Jerry

Assaf said:
hi jon

i am a little confused about lock vs. volatile.
as far as i understand,
there is no corelation between the two concepts!

why do people keep refering to 'locking'
when i am talking about 'caching' (volatile)?

i just took a look at the Interlocked class that you mentioned,
and there is no mention there that the variable will not be cached!

in any case,
as to your statement:
'No, long is not volatile by default'
what do you base it on?

if it is not volatile,
it might be cached,
in which case, i'll solve it,
but not by means of a lock,
unless the compiler is smart not to cached variables
accessed in locked sections

(which i doubt it does,
it would certainly degrade performatnce
not to use caching for all variables
in locked sections)

assaf
 
A

Assaf

hi Jerry.

you are quoting Win32?
what has that got anything to do with .NET?

assaf

Jerry III said:
If you use a lock the compiler might still "cache" (I really have no idea
what you mean by that as compiler doesn't cache anything, the CPU caches the
memory - maybe you're talking about optimizations where the compiler decides
not to fetch the variable from the memory but rather uses a register value
left over from some previous computing) but the CPU cache will be refreshed
every time you use a locking function (such as when you acquire/release a
lock) or when you use an interlocked function. For details you should read
the documentation, Win32 API docs is very detailed about this (and it's
generic enough so it doesn't really apply to Win32 API only but to any code
running on pretty much any CPU, even though the implementation details vary
by CPU). I suggest you start here:
http://msdn.microsoft.com/library/en-us/dllproc/base/synchronization.asp -
the About Synchronization section is really useful.

Jerry
 
J

Jerry III

Because the Win32 documents explain how the hardware handles memory access.
..Net only wraps this in a nice package for you, the basics are still the
same. If you understand how memory is being accessed in general then you
would understand the different options .Net gives you.

Jerry
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top