C++Talk.NET Forum Index C++Talk.NET
C++ language newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

how to prevent unwanted hoist

 
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ Language (Moderated)
View previous topic :: View next topic  
Author Message
andrew_nuss@yahoo.com
Guest





PostPosted: Thu May 17, 2007 1:14 pm    Post subject: how to prevent unwanted hoist Reply with quote



Hi,

Lets say that I have an AtomicCounter whose declaration is:

class AtomicCounter {
volatile long val;

public:
AtomicCounter();
~AtomicCounter();
long ValueOf () { return val; }
void Increment () { InterlockedIncrement(&val); }
};

And I use it in a function in one thread. In this thread, I only use
the ValueOf() member which I'm quite afraid the compiler might think
is immutable, and hence only check the value once.

class MyStream {
AtomicCounter* counter; // set in constructor
char* buf; // alloced in constructor
int buflen;
int bufpos;
long lastcount;
... // other members


void FillBuf ()
{
... refill buffer
lastcount = counter->Value();
}

public:

char NextChar ()
{
bool dirty = false;
do {
if (dirty || bufpos == buflen)
FillWindow();
char ch = buf[bufpos++];
if (counter->ValueOf() == lastcount)
return ch;
cursor == bufpos--;
dirty = true;
} while (true);
}
};

The point is that ValueOf() might be hoisted by an overly smart
compiler because it appears that counter->Increment() is never called
in the NextChar() function nor the FillWindow() function and so the
compiler thinks it only has to fetch ValueOf() once. Nevertheless,
another thread shares the same counter pointer, and could call counter-
Quote:
Increment() at any time.

I'm wondering if the fact that ValueOf() is not a const function and
the AtomicCounter data member is volatile helps any. Otherwise, what
do I do?

By the way, I think my AtomicCounter works fine on Windows, because
InterlockedIncrement() guarantees that another CPU instantly "sees"
the updated "val" member. On Unix, I have further trouble. I think
that Increment() and ValueOf() both need to use a mutex to ensure that
changes to "val" are seen instantly by the other CPU thread. Then
ValueOf() becomes way to slow for the performance of NextChar(). I
wish ValueOf() didn't need to use the mutex.

Thanks,
Andy


--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Back to top
Pedro Lamarão
Guest





PostPosted: Thu May 17, 2007 11:15 pm    Post subject: Re: how to prevent unwanted hoist Reply with quote



On May 17, 10:14 am, "andrew_n...@yahoo.com" <andrew_n...@yahoo.com>
wrote:

Quote:
The point is that ValueOf() might be hoisted by an overly smart
compiler because it appears that counter->Increment() is never called
in the NextChar() function nor the FillWindow() function and so the
compiler thinks it only has to fetch ValueOf() once. Nevertheless,
another thread shares the same counter pointer, and could call counter-

Increment() at any time.

I'm wondering if the fact that ValueOf() is not a const function and
the AtomicCounter data member is volatile helps any. Otherwise, what
do I do?

Since the compiler is forbidden to assume anything about the current
value of a volatile object, it can never assume anything about the
result of calling ValueOf. I don't think any compiler will "cache"
this result. I think you are safe.

--
Pedro Lamarão



[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Back to top
Denise Kleingeist
Guest





PostPosted: Sun May 20, 2007 6:57 am    Post subject: Re: how to prevent unwanted hoist Reply with quote



Hello Andrew!
On May 17, 3:14 pm, "andrew_n...@yahoo.com" <andrew_n...@yahoo.com>
wrote:
Quote:
class AtomicCounter {
volatile long val;

The next revision of the C++ standard will provide support for
atomic operations. The exact details are still under discussion
and currently I can't come up with the exact notation how this
would look like.

In any case, declaring your variable to be volatile won't have
much of an effect with respect to multiple threads accessing it
simultanously. Neither current nor future compilers will honour
it in a form useful for multi-threading purposes. However, it
should already prevent the compiler from hoisting access to it
from the loop but since it doesn't introduce any kind for memory
fences, that's about it.

Good luck, Denise


--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Back to top
Le Chaud Lapin
Guest





PostPosted: Sun May 20, 2007 11:48 pm    Post subject: Re: how to prevent unwanted hoist Reply with quote

On May 20, 1:57 am, Denise Kleingeist
<denise.kleinge...@googlemail.com> wrote:
Quote:
Hello Andrew!
On May 17, 3:14 pm, "andrew_n...@yahoo.com" <andrew_n...@yahoo.com
wrote:

class AtomicCounter {
volatile long val;

The next revision of the C++ standard will provide support for
atomic operations. The exact details are still under discussion
and currently I can't come up with the exact notation how this
would look like.

In any case, declaring your variable to be volatile won't have
much of an effect with respect to multiple threads accessing it
simultanously. Neither current nor future compilers will honour
it in a form useful for multi-threading purposes. However, it
should already prevent the compiler from hoisting access to it
from the loop but since it doesn't introduce any kind for memory
fences, that's about it.

This is a good point.

It is not clear to me what the OP's algorithm is, but the presence of
an unbalanced synchronization primitive is highly suspect.
InterlockedIncrement only guarantees atomicity with respect to other
Interlocked* functions. A naked increment will ruin the point of
using Interlocked* in the first place. This principle is not specific
to Windows.

In other words, there is a model/mood for doing synchronization that
the compiler cannot provide, and must be conscientiously engineered by
the programmer, then, after that, the elements of synchronization in
the language and the library can be brought to bear upon the design.

-Le Chaud Lapin-


--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Back to top
Display posts from previous:   
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ Language (Moderated) All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.