it's a rough rough rough draft
Andrei Alexandrescu
andrei at metalanguage.com
Fri Sep 10 02:57:23 BST 2004
> We can't possibly turn this into a threads introduction.
> Nor do I think we should try. We should reference one.
> I think Andrew Birrell's "An Introduction to Programming
> with C# Threads"
> (http://research.microsoft.com/~birrell/papers/ThreadsCSharp.pdf)
> is probably fine, and has a good intro,
> though some of the finer details don't carry
> over. Anyone know of a better one?
I think referring people to Butenhof's book on pthreads is the best thing to
do.
The point is not to include a tutorial on threads, but rather a tutorial on
memory visibility. As I told Doug, most people on the committee do
understand lock-driven programming where you acquire a lock and then see
everything everybody ever did and can do anything you want. Then they try to
integrate an understanding of memory model within that simple framework, and
they hit a brickwall.
I've had a very very relevant exchange with a gentleman on clc++m that has
this exact pattern: "I'm not an expert on threads, but I would like to
understand these things you are referring to". Me: "Here's some info, and
here are some references." Him (furious): "I don't have the time and the
inclination to read the references, but what you say makes no sense. You are
snooty. I claim to have a pretty good understanding of threads, and what you
say makes absolutely no sense in that framework, so my conclusion is that
you are enjoy acting precious by using obscure language and not discussing
your views." (Of course, not in these exact words, but that's the impression
I've gotten.)
We should prevent such a reaction.
> Section 4:
>
> The core of the new Java memory model is to classify synchronization
> operations as "acquire" (e.g. lock acquisition) or "release" (e.g. lock
> release) operations on some synchronization object. A "release"
> operation has the effect (among others) of ensuring that all memory
> operations performed by a thread before the "release" operation
> become visible to another thread after it performs a corresponding
> "acquire" operation. Thus, for example a thread that acquires a lock
> is guaranteed to see all updates that occurred while another thread
> held the same lock.
Java needed to do that because the synchronization object were implicit
(though I know Java 1.5 has explicit ones as well), but for C++ I think
synchronization objects should be separate from the memory model. In wake of
Doug's idea that the library and memory model proposals could be separate, I
think it's easier to go a different route: We define terms such as memory
barriers, weak read, strong read, weak write, and strong write, and later
on, when we define synchronization objects and whatnot, we mention what they
do in terms of the notions we defined in the memory model.
> Section 5:
>
> I would make this much more tentative, e.g. start with:
>
> We are planning to propose a set of atomic operations on shared memory
> locations to support lock-free programming. For each such operation
> we will need to specify not only its function, but also the ordering
> constraints it imposes, e.g. whether it behaves as an "acquire" or
> "release" operation, or neither or both. For many operations
> multiple variants make sense. We are currently undecided as
> to both the syntax of these constraints, and how many variants there
> should be. Thus we omit them for the rest of this presentation.
Sounds good, though people might confuse lock-free programming with the
whiz-bang lock-free programming that has become popular nowadays. But said
primitives can be used for much more conservative purposes, such as
manipulating the reference count of a smart pointer.
> I think cas should be one of the atomic_ primitives.
Ok. By the way, I have two questions I'd like to ask:
1. Is there any machine of any importance to anyone that has threads but no
CAS (or some way of implementing it efficiently)?
2. Couldn't the compiler use CAS to resolve the word tearing problem? I
might be wrong here, but to me it seems like any word tearing problem can be
solved if the compiler generates appropriate looped CAS to generate a proper
read-modify-write sequence. Now things might be less efficient, but I don't
know by how much.
> In any case, atomic_add needs to return a value.
Yah, and also I'm unsure whether int is the appropriate second parameter
type.
> (Actually, I can think of a reason to diverge from it, which would
> be to have a single interface for both C and C++. But I doubt that
> would fly. And eventually there may be reasons to supply the
> ordering semantics as a template argument.)
Hmmm, that's a good question for later: how easy will we make the memory
model "translatable" to the folks in the C std committee?
> Section 6:
>
> We plan to consider giving an assignment to a "volatile" variable
> or field "release" semantics, and read a "volatile" "acquire"
> semantics. This is true for both the new Java memory model and
> the current C/C++ ABI for Itanium. This would better specify
> the semantics of "volatile" and allow clean solutions to some common
> concurrent programming problems for which locks often introduce
> too much overhead. But we have not yet had enough time to fully
> understand the consequences for C++.
That's great, and reflects my current view exactly.
Andrei
More information about the cpp-threads
mailing list