volatile and threading

A

Agras

I have a shared variable between threads:
volatile int a;

Inside threads, `a` will be increased (a++) and decreased (a--) many
times without mutexes.

I believe this is correct, because a++ and a-- needs only one assembly
instruction.

Am I right, or mutexes are needed?

Thanks
 
C

Chris Thomasson

Agras said:
I have a shared variable between threads:
volatile int a;

Inside threads, `a` will be increased (a++) and decreased (a--) many times
without mutexes.

I believe this is correct, because a++ and a-- needs only one assembly
instruction.

Am I right, or mutexes are needed?

Memory visibility aside, something needs to guard the RMW operation...
Hardware-Specific instructions are in need indeed! ;^)
 
A

Agras

O/H Chris Thomasson Ýãñáøå:
You can use volatile and a++/-- if you simply don't care about the
accuracy of the counter and/or memory visibility wrt the counter state
in any way, shape or form. For instance, in a non-atomic increment
operation on a shared location S where S == 0; CPU's A, B and C can load
the value 0 from S; and all subsequently store 1 into S; therefore
rendering S == 1, when it clearly should have been S == 3! If you simply
don't care about that, then your free to use "naked" increments and
decrements...

thanks a lot.
I don't care about variable's state while threads running. So I can use
"naked" ++/--.

Thanks again.
O
 
K

Kira Yamato

I have a shared variable between threads:
volatile int a;

Inside threads, `a` will be increased (a++) and decreased (a--) many
times without mutexes.

I believe this is correct, because a++ and a-- needs only one assembly
instruction.

Am I right, or mutexes are needed?

Hmm... I can't seem to see why a standalone statement
a++;
or
++a;
would need mutex protection since you are not reading its value while
changing it.

Perhaps you are using the expression a++ in a large context, like
if (a>0)
--a;
in which case you will certainly need mutex protection in a
multithreaded environment.
 
C

Chris Thomasson

Chris Thomasson said:
Memory visibility aside, something needs to guard the RMW operation...
Hardware-Specific instructions are in need indeed! ;^)

You can use volatile and a++/-- if you simply don't care about the accuracy
of the counter and/or memory visibility wrt the counter state in any way,
shape or form. For instance, in a non-atomic increment operation on a shared
location S where S == 0; CPU's A, B and C can load the value 0 from S; and
all subsequently store 1 into S; therefore rendering S == 1, when it clearly
should have been S == 3! If you simply don't care about that, then your free
to use "naked" increments and decrements...
 
K

Kira Yamato

Hmm... I can't seem to see why a standalone statement
a++;
or
++a;
would need mutex protection since you are not reading its value while
changing it.

Ok, i see one instance where mutex protection is needed right now. :)

If two threads try to execute "a++;" then it is possible, depending on
hardware implementation, to have incorrectly only one increment instead
of the correct increment of 2.

Sorry about that.
 
G

Gianni Mariani

Agras said:
I have a shared variable between threads:
volatile int a;

Inside threads, `a` will be increased (a++) and decreased (a--) many
times without mutexes.

I believe this is correct, because a++ and a-- needs only one assembly
instruction.

Am I right, or mutexes are needed?

You are not right. There are solutions though - take a look at "atomic
int" or at some austria C++ sources.

The next version of the standard will have support for atomic
increment/decrement operations and threading. In the meantime, this is
what I have done:

http://austria.svn.sourceforge.net/viewvc/austria/src/austria/code/at_atomic.h?view=markup

at_atomic.h has implementations for GCC/x86 32 and 64 and Win32 and
powerpc/darwin.


x86_32 and x86_64 implementations
http://austria.svn.sourceforge.net/.../code/at_gx86_atomic.h?revision=1&view=markup

powerpc implementation
http://austria.svn.sourceforge.net/...ode/at_darwin_atomic.h?revision=1&view=markup

win32 implementation
http://austria.svn.sourceforge.net/...code/at_win32_atomic.h?revision=1&view=markup
http://austria.svn.sourceforge.net/...de/at_win32_atomic.cpp?revision=1&view=markup

There are long discussions about visibility and the need to help the CPU
sync the cache. See aquire and release semantics. Using a mutex will
do all of that for you, however, you don't always want to pay for the
cost of a mutex.
 
G

Gianni Mariani

Chris said:
You can use volatile and a++/-- if you simply don't care about the
accuracy of the counter and/or memory visibility wrt the counter state
in any way, shape or form. For instance, in a non-atomic increment
operation on a shared location S where S == 0; CPU's A, B and C can load
the value 0 from S; and all subsequently store 1 into S; therefore
rendering S == 1, when it clearly should have been S == 3! If you simply
don't care about that, then your free to use "naked" increments and
decrements...

You can also use a random number generator.
 
A

Agras

O/H Gianni Mariani Ýãñáøå:
You are not right. There are solutions though - take a look at "atomic
int" or at some austria C++ sources.

The next version of the standard will have support for atomic
increment/decrement operations and threading. In the meantime, this is
what I have done:

http://austria.svn.sourceforge.net/viewvc/austria/src/austria/code/at_atomic.h?view=markup


at_atomic.h has implementations for GCC/x86 32 and 64 and Win32 and
powerpc/darwin.


x86_32 and x86_64 implementations
http://austria.svn.sourceforge.net/.../code/at_gx86_atomic.h?revision=1&view=markup


powerpc implementation
http://austria.svn.sourceforge.net/...ode/at_darwin_atomic.h?revision=1&view=markup


win32 implementation
http://austria.svn.sourceforge.net/...code/at_win32_atomic.h?revision=1&view=markup

http://austria.svn.sourceforge.net/...de/at_win32_atomic.cpp?revision=1&view=markup


There are long discussions about visibility and the need to help the CPU
sync the cache. See aquire and release semantics. Using a mutex will
do all of that for you, however, you don't always want to pay for the
cost of a mutex.

I don't know what is mem visibility, but I understand the CPU's cache
problem.

It's clear now.

Your lib seems nice and needs not rtti (I explore the source now).
But I use boost in my code and it's hard to make changes now.
I give it a try in later programs.

thanks!
 
J

James Kanze

I have a shared variable between threads:
volatile int a;
Inside threads, `a` will be increased (a++) and decreased (a--) many
times without mutexes.
I believe this is correct, because a++ and a-- needs only one assembly
instruction.
Am I right, or mutexes are needed?

Mutexes are needed. Or more correctly, it's implementation
defined, but mutexes are needed according to Posix, and at least
with current implementations of Windows and VC++. (I believe
that Microsoft has said that volatile will be sufficient in some
future version.)
 
J

James Kanze

On 2008-01-21 20:09:49 -0500, Agras <[email protected]> said:
Hmm... I can't seem to see why a standalone statement
a++;
or
++a;
would need mutex protection since you are not reading its value while
changing it.

If you only do it in one thread, mutexes aren't needed.
Otherwise: as more than one thread accesses a variable, and any
thread might modify it, some form of synchronization is needed.
(On most processors, it's possible to write an atomic increment
without using mutexes. But you'll likely need some special
hardware instructions to do so, instructions which are never
generated by the compiler.)
 

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

Similar Threads


Members online

No members online now.

Forum statistics

Threads
474,183
Messages
2,570,967
Members
47,520
Latest member
KrisMacono

Latest Threads

Top