The Usage of the volatile Keyword


Following are my notes and understanding from the two referenced documents listed at the end of the article.


0. The volatile keyword tells compiler to turn off optimization for code accessing the modified variable/object, and always
write it to memory/read it from memory, rather than simply writing it to cpu register/reading it from cpu register.

1. A variable/object should be defined volatile if it can be modified by other instructions which are not executed by the current thread of execution,
and at the same time it can be read/written by current thread of execution. Since a thread of execution is run by a single cpu,
thus on multiple cpu systems, variables/objects shared by multiple threads of execution must be volatile, this including global variables
shared by multiple threads of a process, and structures/objects/variables placed in shared system memory/file mapping shared by multiple processes;
and even on a single cpu system, if a variable/object can be modified by a device (device driver) (i.e. not the cpu), it should be volatile.

2. volatile T *ptrT; where T is a structure. In this definition, whichever member ptrT dereferences, that member is written to/read
from memory rather than to/from CPU register. In other words, we tell the compiler that all members of T are volatile, thus always
access memory when accessing T's members through ptrT. type T* is not consistent with type "volatile T*".

And if we define all members in T with volatile, we get identical promise/behavior as above, and we don't have to use 'volatile'
outside when defining pointers/objects of (base) type T. Thus doing so can avoid spreading "volatile" everywhere in the code base, but
also means accesses to objectects of T will never be optimized for faster access.

If no volatile is used inside/outside T, data inconsistency can happen, imagine
two cpus executing two threads and they both are modifying the same object of type T, the final state of the object is unknown.

If T is a primitive type, the behavior is the same --- it takes a volatile keyword to guarantee the variable be accessed consistently if its shared by
multiple threads of execution.

3. The volatile modifier is quite like const modifier in terms of pointer definition. volatile T*ptrT or T volatile *ptrT means
the object(i.e. all members of the object)/variable ptrT points to is volatile; T *volatile ptrT means the pointer ptrT itself is volatile.

4. at thread/process context switch, i.e. thread/process A is about to be replaced by B, the registers that are used to cache variables
should be flushed to memory then cleared to maintain data consistency; and then during B's execution such registers are loaded with new values from memory.


Reference:
http://www.cognitus.net/html/tutorial/usingVolatile.html
http://www.megasolutions.net/cplus/What-is-the-proper-use-of-volatile_-21698.aspx
new values from memory.

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章