High-performance multithreading is very hard

Date:May 28, 2004 / year-entry #211
Tags:code
Orig Link:https://blogs.msdn.microsoft.com/oldnewthing/20040528-00/?p=39133
Comments:    11
Summary:Among other things, you need to understand weak memory models. Hereby incorporating by reference Brad Abrams' discussion of volatile and MemoryBarrier(). In particular, Vance Morrison's discussion of memory models is important reading. (Though I think Brad is being too pessimistic about volatile. Ensuring release semantics at the store of "singleton" is all you really need...

Among other things, you need to understand weak memory models.

Hereby incorporating by reference Brad Abrams' discussion of volatile and MemoryBarrier(). In particular, Vance Morrison's discussion of memory models is important reading.

(Though I think Brad is being too pessimistic about volatile. Ensuring release semantics at the store of "singleton" is all you really need - you want to make sure the singleton is fully constructed before you let the world see it. volatile here is overkill.)

Vance's message also slyly introduces the concepts of "acquire" and "release" memory semantics. An interlocked operation with "acquire" semantics prevents future reads from being advanced to before the acquisition. An interlocked operation with "release" semantics prevents previous writes from being delayed until after the release.

In the absence of explicitly-named memory semantics, the Win32 Interlocked* functions by default provide full memory barrier semantics. However, some functions, like InterlockedIncrementAcquire, forego the full memory barrier semantics and provide only acquire or release semantics.


Comments (11)
  1. Scott Allen says:

    Unfortunately the double check lock pattern was at one time presented as a best practice for singleton construction on MSDN, but I see there are some updates addressing the potential problem: (http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnbda/html/singletondespatt.asp)

    The pattern is everywhere in .NET software these days, including in this .Text blog software. .Text has a different threading problem in trying to avoid a lock for a performance gain:(http://odetocode.com/Blogs/scott/archive/2004/05/26/259.aspx)

  2. Mike Dimmick says:

    See also Chris Brumme’s Memory Model post for acquire and release information: http://blogs.msdn.com/cbrumme/archive/2003/05/17/51445.aspx

  3. Karl Barrus says:

    Double checked locking is indeed broken: http://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html

    Scott Meyers was in town a few months ago and gave a talk on this very talk. Quite interesting.

  4. Raymond Chen says:

    That’s why you need the memory barrier with release semantics. Once you have that, you’re safe again.

  5. Karl Barrus says:

    Cool, I was just posting for information. Meyer’s talk was about portable code so what was interesting was the fact so much is left out of the C++ standard. (The paper is on Java but Meyers did a C++ version of the talk).

  6. Alexei Zakharov says:

    Slides from the talk Scott Meyers did a couple of months ago are here: http://www.nwcpp.org/Downloads/2004/DCLP_notes.pdf

    He actually shows the protocol that has to be followed to get the double checked locking right in the weakest memory model possible (as defined in the C++ standard). I’m glad he did that because otherwise you have to dig that information from comp.programming.threading and it ain’t easy.

  7. Pavel Lebedinsky says:

    Ensuring release semantics at the store of "singleton" is all you really need

    You also need an acquire barrier between reading the "ready" flag and reading the data (the Scott Meyers link that Alexei posted mentions that).

    I also agree with Meyers that the rule of thumb should be "if you access shared data, protect it with a lock".

    It’s only when you discover that locking is a bottleneck that you should start thinking about lock free algorithms, memory barriers etc. (And even then the right solution often is simply to change the design so that you lock less often or don’t hold locks for too long).

  8. brian says:

    I’m surprised to hear that MSDN was promoting double-check-lock as best practice. I recall first hearing about this anti-pattern in Java a few (maybe >= 4) years ago, and then how it was debunked as unsafe. Even after that, it was used in a Sun-supplied solution to the "Question of the Week" on their site (they’ve since fixed it: http://java.sun.com/developer/qow/archive/111/ ).

  9. Raymond Chen says:

    Commenting on this entry has been closed.

Comments are closed.


*DISCLAIMER: I DO NOT OWN THIS CONTENT. If you are the owner and would like it removed, please contact me. The content herein is an archived reproduction of entries from Raymond Chen's "Old New Thing" Blog (most recent link is here). It may have slight formatting modifications for consistency and to improve readability.

WHY DID I DUPLICATE THIS CONTENT HERE? Let me first say this site has never had anything to sell and has never shown ads of any kind. I have nothing monetarily to gain by duplicating content here. Because I had made my own local copy of this content throughout the years, for ease of using tools like grep, I decided to put it online after I discovered some of the original content previously and publicly available, had disappeared approximately early to mid 2019. At the same time, I present the content in an easily accessible theme-agnostic way.

The information provided by Raymond's blog is, for all practical purposes, more authoritative on Windows Development than Microsoft's own MSDN documentation and should be considered supplemental reading to that documentation. The wealth of missing details provided by this blog that Microsoft could not or did not document about Windows over the years is vital enough, many would agree an online "backup" of these details is a necessary endeavor. Specifics include:

<-- Back to Old New Thing Archive Index