[cpp-threads] infinite loops

Boehm, Hans hans.boehm at hp.com
Thu Aug 17 21:40:29 BST 2006


If we look back at the original loops:

> > Thread 1a:
> > for (foo *p = q; p != 0; p = p -> next)
> >     if (p -> data == 17) count17++;
> > for (foo *p = q; p != 0; p = p -> next)
> >     if (p -> data == 13) count13++;

The current draft proposal (which I think Clark will circulate shortly)
would invoke unspecified behavior if q points to a circular list and the
loop does not include an acquire operation.  Thus we're telling the
programmer not to invoke such a loop on a circular list unless he/she
knows that ++ invokes an acquire operation.  I claim it would be
incredibly bad taste to write such a loop unless either, both count17 or
count13 are atomics, or an explicit acquire operation is added to the
loop.

As far as the programmer is concerned, there is no difference whether ++
is a user-defined operation on some complex data type or the integer ++.
The only thing that matters is whether it has acquire semantics.  And
that's the kind of thing you need to know in other contexts for
multithreaded correctness anyway.  (And the current draft proposal
applies this rule only to multithreaded code, to avoid breaking any
exisiting standard-conforming code.)

Clearly the performance of the resulting code will be somewhat
unpredictable depending on whether the compiler understands the
semantics of ++.  But that's nothing new.  Correctness is not affected.

Hans

> -----Original Message-----
> From: Lawrence Crowl [mailto:lawrence.crowl at gmail.com] 
> Sent: Thursday, August 17, 2006 1:19 PM
> To: Boehm, Hans
> Cc: C++ threads standardisation
> Subject: Re: [cpp-threads] infinite loops
> 
> On 8/17/06, Boehm, Hans <hans.boehm at hp.com> wrote:
> > > From: Lawrence Crowl
> > >
> > > On 8/16/06, Boehm, Hans <hans.boehm at hp.com> wrote:
> > > > Clearly the transformation is invalid if either count13 or
> > > count17 is
> > > > volatile or atomic, or if an opaque function call is involved.  
> > > > But lots of compiler loop transformations that we do 
> all the time 
> > > > have similar restrictions.  (If memory mapped I/O were involved,
> > > one of the
> > > > above better apply.)
> > >
> > > So, the two statements
> > >
> > >     f = 1.0; c = 1.0;
> > >
> > > have different synchronization effects when
> > >
> > >     float f; std::complex<float> c;
> > No, though the compiler may know less about the synchronization 
> > effects of the latter.
> >
> > I think we're misunderstanding each other.  They do have different 
> > optimization effects if std::complex operations are treated 
> as opaque 
> > by the compiler.  But that's already the case, and we all 
> knew that.  
> > If the compiler knows about std::complex, or performs 
> transformations 
> > after those operations are inline expanded, it should be able to 
> > perform the same transformations in both cases.
> 
> And my point is that, to the programmers, the behavior is 
> unpredictable.
> Programmers cannot generally know what is opaque or what 
> transformations may apply in any given environment.
> 
> How will programmers write reliable multi-threaded code if 
> they cannot predict, from the standard, what their code will do?
> 
> --
> Lawrence Crowl
> 



More information about the cpp-threads mailing list