atomic<T> (from my understanding) has operators operating on (naturaly aligned) volatile'd variables (look at the primitives in TBB's atomic.h)
volatile though does not assure the variable is aligned on a natural boundry
(natural boundry variables can be atomicaly R, W, or LOCK RMW).
volatile does assure that the compiler will always generate code to reference memory
atomic<T> typed variables are aligned on natural boundry.
Therefore atomic typed variables, when used internaly with volatile, are assured to atomically R, W, or LOCK RMW.
volatile alone typed variables are not assured to be aligned on natural boundry, therefore are NOT assured to atomically R, W, or LOCK RMW...
...UNLESS the programmer takes caution to enforce alignment rules on such declared variables.
atomic<T> typed variables are permitted to have some optimizations performed on them
Some of these optimizations may interfere with multi-threaded programming.
atomic<int> line = 0;
...
line = 1;
line = 2;
compiler is permitted to remove first statement. Therefore, if other thread is monitoring progress, it will never see line=1.
Be cautious in assuming atomic<T> variables will perform as you intend. If you require some probability of reading all instances of (programmed) writes then do not use atomic, use volatile.
volatile int line = 0;
...
line = 1;
line = 2;
compiler is NOT permitted to remove first statement.
however, it is not required to align line on natural boundry.
A stack local int variable will tend to be naturally aligned.
A structure member variable is not assured to be naturally aligned
A a programmer, you are required to assure alignment (when atomnicity is required).
Jim Dempsey