volatile is a type qualifier in C/C++. Data that is marked as volatile is observable to something other than the compiler. Doing this tells the compiler not to optimise anything associated with the variable, because its value may change outside of the compiler’s detection.
- For example, successively writing to a pointer would ordinarily be optimised out. However, for a memory-mapped IO device, this can meaningfully change the result of the program.
- The compiler will also not reorder
volatilereads and writes with respect to othervolatileones. Note that this does not give us atomicity for safe inter-thread communication.
The main use of volatile is for interfacing with hardware via memory-mapped IO that changes the value itself, as opposed to within the program. In an embedded context, this forces the program not to look at the cache for the data, but instead a connected I/O device.
In Nios and ARM, using
volatiletells the compiler to useldwioandstwioinstructions instead ofldwandstw.
When to use:1
- Hardware interaction (like when writing drivers).
- Memory-mapped files or I/O.
- To “touch” memory.
- Basically the premise is that: memory might be swapped out to disk. Then, a thread might try to acquire a lock, but the memory is on disk. So the lock might be held for multiple ms instead of a typical couple of us.
- We basically read ahead of time (even if it makes no sense to the compiler or is garbage). This puts it in the cache, so it’s hot and we don’t have to wait too long for a lock.
- For “multithreading”. By tagging data as
volatile, the compiler won’t re-order a sequence of operations that might be logically equivalent in a singlethreaded environment but changes the workflow in concurrent execution. There are several caveats here:- This doesn’t actually give us atomicity or “safe” inter-thread communication.
- The compiler is free to re-order all loads/stores around the volatile instructions.
- On weakly-ordered (eventually consistent) systems, compilers won’t emit memory barriers.
Footnotes
-
From Advanced C: The UB and optimizations that trick good programmers, by Eskil Steenberg. ↩