Re: C++ Threads, what's the status quo?
Le Chaud Lapin wrote:
Pete Becker wrote:
Le Chaud Lapin wrote:
[sample code by Chaud Lapin reaffirming what Pete wrote]
Technically, IIUC, the compiler has the right to reorder these two
statements, since they are visibly independent, thus launching the
missile at a potentially friendly neighboring country and subsequently
pointing the launch pad at the enemy.
Yup. And embedded programmers have to be very careful about what the
compiler does in order to make that sort of code work right. In
particular, you'd test that the code actually executed in the required
order. Do you propose doing that for every lock and unlock in a
Well, I guess there are two options.
One, the whole issue of optimization (statement reordering in
particular) needs to be addressed (no pun intended), which is, in way,
separate from multi-threading, but definitely affects it.
The issue has been addressed. It very much conditionned the
wording in '1.9, the concept of sequence points, and the
undefined behavior in '5/4 (which many of us would like to see
tightened), for example. The problem is that the way it was
addressed has no meaning for multithreaded code.
Not sure if the people who like optimization will scream if
someone says, "You need to turn the optimizer off" if you want
your code to execute correctly.
You bet they will. Some people need all the performance they
can get. (I'm not one of them, and I don't normally use the
optimizer, even on delivered code. But I've talked to people
who do need performance.)
Note that C99 goes one step further, and has added a new keyword
(restrict) solely to allow the programmer to pass additional
information to the optimizer; restrict has no effect whatsoever
unless the compiler is trying to optimize code.
The other issue would be to add extra keywords to the language which
would be particular to threading that would prevent the compiler from
statement reordering. But then, I guess you would want to make those
keywords not thread-specific but useful in general.
The problem is that enforcing ordering, in general, would mean
slowing up even unoptimized code by a factor of maybe 5, on a
modern machine. (It means that you'd have to insert fences
between every access, in order to prevent hardware re-ordering.)
And it isn't at all necessary; all you need and want is that at
certain, well defined instances, all previous writes are
completed, and no following reads have started. Posix requires
functions like pthread_lock and pthread_unlock to provide this,
in addition to their functionality on the mutex. In practice,
Windows does too, although I've never seen it documented. Which
means that if you use the system primitives for synchronization
on these systems, all you have to worry about is compiler code
movement. Posix provides guarantees for this as well, at least
for C; I've not seen similar written guarantees for Windows, but
I can't imagine VC++ doing otherwise.
Part of the goal in standardizing is to define a set of
functions which provides such guarantees. (Note that in this
case, library and language overlap. The language allows code
movement, except over such and such a function.)
For me, a lot of people are not going to like this, but if the compiler
did that with my code, I would turn off optimization for affected code,
which means not using macros for synchronization, etc. Not the best
That's life. Slowing all programs down by a factor of 5 isn't
the best solution, either, and making all reasonable
optimization impossible (and slowing some numeric programs down
by a factor of maybe 20) isn't a particularly good solution
James Kanze (GABI Software) email:email@example.com
Conseils en informatique orientie objet/
Beratung in objektorientierter Datenverarbeitung
9 place Simard, 78210 St.-Cyr-l'Icole, France, +33 (0)1 30 23 00 34
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]