9 ms·
Thanks again. If I am right though, the memory barriers could also have been skipped without thread-local values since, due to the barriers on init, no thread's
by vy8vWJlco 13y ago
Thanks again. If I am right though, the memory barriers could also have been skipped without thread-local values since, due to the barriers on init, no thread's view would revert to it's pre-init state anyway. As rbehrends mentions, barriers are not the only factor... For example, global memory access may be slower on some systems due to decreased locality (a property provided by the TLS), but I don't know what if any value that would have in this benchmark. There is also a comment on that page that does the same thing as my TLS-free approach using a more reasonable static global initialization syntax in Java in response to a question of if D's initialization would be semantically equivalent too.
Edit: (Not waiting for reply link to appear...) When I say "the memory barriers could also be skipped" I am referring to any other memory barriers past those associated with initialization, not those associated with initialization. There would be memory barriers at initialization, but that is the only need for memory barriers and I believe that is provided here by the synchronized keyword. The object presented in the article then looks like a cache-friendlier version of a single global variable with the necessary barriers limited to the initialization of the global instance pointer (which might also be done as in the Java example given in the comments on the page). The TLS does not eliminate the need for any barriers, only helps eliminate non-local reads. That might allow a performance gain depending on the cache behavior (or, for example, in the presence of NUMA), but it hasn't reduced the need for locking IMHO.
- WalterBright 13y agoIf multiple threads are accessing two globals, two threads are not guaranteed to see changes in one or the other in the same order. This is called "sequential consistency". The only way to get sequential consistency between threads is to insert memory barriers or use synchronization. There is no way around this. Your statement that memory barriers could be skipped is exactly the source of the double checked locking bug. I know this is hard to understand, which is why it has tripped up a looong list of very smart people over the years. David's article solves the problem by having one of the globals not be global at all, but thread local. As for performance, David's article shows with benchmarks that his solution is a huge win.
- deleted 13y ago[deleted]