> N.B. Accessing registers modified by the hardware may be treated as a multi-threaded application. Therefore, it is worth considering using std::atomic<T> instead of volatile T.
This is incorrect. Compilers are allowed to reorder and combine atomics as long as they follow the rules. See: https://github.com/jfbastien/no-sane-compiler