The trouble with volatile
lwn.net
lwn.net
Third, avoid using a lazily-initialized Singleton unless
you really need it. The classic Singleton implementation
is based on not initializing a resource until that
resource is requested. An alternative is to use eager
initialization instead, i.e., to initialize a resource at
the beginning of the program run.
I've personally never found the need for a lazy-loaded singleton and I expect the same to be true for most other software developers. This whole problem stems from the premature optimization of thinking lazy-loading something would be nifty.Standard C and C++ do not have a memory model and do not support multi-threading at the language level. You have to rely on compiler-specific libraries/APIs, or C++0x (which has a memory model).
Let's say you have a variable that's used as a flag for communication between two threads. Protecting it with spin_locks inside a thread that checks the flag repeatedly inside a loop is not going to prevent compiler from optimizing that access away -- because as far as the compiler is concerned, value of that flag does not change inside that loop -- period.
It appears that the real recommendation of the article is to process shared data in special functions that access them by dereferencing a pointer. I don't see how that's more efficient/effective for simple cases like described above than declaring a volatile variable.
I just want to point out that there ARE cases where you MUST use volatile in userland. For instance, double-checked locking (see this Scott Meyers essay on DDJ for info: http://www.aristeia.com/Papers/DDJ_Jul_Aug_2004_revised.pdf) is only guaranteed to work on the MSCV compiler as of the 2005 release (and others at different versions) with volatile bools (though the same caveats mentioned on LWN will apply): http://en.wikipedia.org/wiki/Double-checked_locking#Usage_in...
The singleton is something which the majority of programmers understand vs realizing that the runtime can optimize reads and writes to memory by doing things which make sense in the context of one thread but break in multiple is something I'd only expect the top 10% (and that may be generous) of programmers to understand.
So having the complex part be an intuitive (but wrong) optimization to the easy bit is just a deadly combination.