volatile is ignored by my compiler?

Hi,

I am using g++ to compile my C++ code.

Here is the simplified code:

class A {
     public:
         void change();
         void doSomething();
     private:
         volatile bool ready;
}

A::A() : ready(false) {}

A::change() {
     printf("changed!\n");
     ready=true;
}

A::doSomething() {
     // the actual code is not an infinite loop but very close --
doSomething is being called at very high frequency without a while
loop.
     while(true) {
         if (ready) printf("it is ready\n");
         else printf("it is not ready\n");
     }
}

One of the threads will call A.change(), and another thread will call
A.doSomething().
Sometimes, I have the following output:
it is not ready
it is not ready
it is not ready
changed!
it is not ready
it is not ready
it is not ready
it is not ready

And I let the program continue for few minutes.  It still prints "it
is not ready".

Any idea?

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

0
Hei
11/10/2009 2:28:56 AM
comp.lang.c++.moderated 10738 articles. 1 followers. allnor (8506) is leader. Post Follow

19 Replies
339 Views

Similar Articles

[PageSpeed] 29

On 10 Nov., 09:28, Hei <hchan1...@gmail.com> wrote:
> Hi,
>
> I am using g++ to compile my C++ code.
>
> Here is the simplified code:
>
> class A {
>      public:
>          void change();
>          void doSomething();
>      private:
>          volatile bool ready;
>
> }
>
> A::A() : ready(false) {}
>
> A::change() {
>      printf("changed!\n");
>      ready=true;
>
> }
>
> A::doSomething() {
>      // the actual code is not an infinite loop but very close --
> doSomething is being called at very high frequency without a while
> loop.
>      while(true) {
>          if (ready) printf("it is ready\n");
>          else printf("it is not ready\n");
>      }
>
> }
>
> One of the threads will call A.change(), and another thread will call
> A.doSomething().
> Sometimes, I have the following output:
> it is not ready
> it is not ready
> it is not ready
> changed!
> it is not ready
> it is not ready
> it is not ready
> it is not ready
>
> And I let the program continue for few minutes.  It still prints "it
> is not ready".
>
> Any idea?

{ edits: quoted banner removed. please don't quote the banner. -mod }

Are you sure that you use the same instance of A when calling
doSomething?

Peer


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

0
Peer
11/10/2009 7:02:37 AM
> And I let the program continue for few minutes.  It still prints "it
> is not ready".
>
> Any idea?

Are you sure your threads are accessing the _same_ instance of class A you
are using and not that each thread is accessing it's own thread local copy?

You could test this easily by adding printfs to display "this" pointer & see
if they match!

void A::change() {
     printf("change this=%p\n", this);
      printf("changed!\n");
      ready=true;
}

void A::doSomething() {
     printf("doSomething this=%p\n", this);
      while(true) {
                 if (ready) printf("it is ready\n");
          else printf("it is not ready\n");
      }
}

If they don't print equal then you are definately using different instances.
If they do print equal I'd need more code to see what the problem is.

Hope this helps.

Chris



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

0
Chris
11/10/2009 7:03:06 AM
Hei wrote:
> 
> And I let the program continue for few minutes.  It still prints "it
> is not ready".
> 
> Any idea?
> 

Does the compiler's documentation tell you that this will work? The 
language definition does not require volatile to impose synchronization 
on a variable that's accessed from multiple threads. If one thread is 
running on one CPU and the other thread on another CPU, writing from one 
thread writes to that CPU's cache; the other CPU has its own cache, and 
won't see that change until the write is flushed to main memory and the 
previously read value is replaced from main memory. To make that happen, 
you need synchronization; typically through a mutex or a condition variable.

-- 
   Pete
Roundhouse Consulting, Ltd. (www.versatilecoding.com) Author of
"The Standard C++ Library Extensions: a Tutorial and Reference"
(www.petebecker.com/tr1book)

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

0
Pete
11/10/2009 3:30:50 PM
On Nov 10, 9:28 am, Hei <hchan1...@gmail.com> wrote:
> Hi,
>          volatile bool ready;
>
> A::A() : ready(false) {}
>
> A::change() {
>      printf("changed!\n");
>      ready=true;
>
> }
>
> A::doSomething() {
>      // the actual code is not an infinite loop but very close --
> doSomething is being called at very high frequency without a while
> loop.
>      while(true) {
>          if (ready) printf("it is ready\n");
>          else printf("it is not ready\n");
>      }
>
> }
>
> One of the threads will call A.change(), and another thread will call
> A.doSomething().

The semantics of volatile are very specific, and they are intended to
read and write special memory locations (e.g. memory-mapped I/O
registers of periphery), not for thread communication. Volatile forces
the compiler to assume that the variable can change unexpectedly, that
simply writing or even reading it can have side effects, and thus to
never lift it to a register or reorder/omit accesses.
Volatile does not force the CPU(s) to do anything, though. You're
accessing a simple variable, an ordinary memory location. The CPU,
unlike the compiler, isn't fooled by you - it knows that no periphery
is going to change this location. Any core therefore can, depending on
the architecture's cache consistency model, hold the variable in its
private cache and keep reading the cached version, never noticing that
another core changed the memory location. What you need is atomic
access. Only then can you reliably and portably use a variable as a
ready flag.
Standard C++ doesn't yet have atomic variables. But various thread
libraries offer them.

All that said, if you're on an x86, all the above doesn't mean much,
because the architecture's cache consistency model should force the
change to be detected pretty soon.


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

0
CornedBee
11/10/2009 3:32:15 PM
Hei schrieb:
> Hi,
> 
> I am using g++ to compile my C++ code.
> 
> Here is the simplified code:
> 
> class A {
>      public:
>          void change();
>          void doSomething();
>      private:
>          volatile bool ready;
> }
> 
> A::A() : ready(false) {}
> 
> A::change() {
>      printf("changed!\n");
>      ready=true;
> }
> 
> A::doSomething() {
>      // the actual code is not an infinite loop but very close --
> doSomething is being called at very high frequency without a while
> loop.
>      while(true) {
>          if (ready) printf("it is ready\n");
>          else printf("it is not ready\n");
>      }
> }
> 
> One of the threads will call A.change(), and another thread will call
> A.doSomething().
> Sometimes, I have the following output:
> it is not ready
> it is not ready
> it is not ready
> changed!
> it is not ready
> it is not ready
> it is not ready
> it is not ready
> 
> And I let the program continue for few minutes.  It still prints "it
> is not ready".
> 
> Any idea?
> 

Volatile has nothing to do with threads (and ISO-C++ doesn't know
anything about threads until C++0x). You have to use a mutex to
synchronize the memory between your threads.


Lars

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

0
Lars
11/10/2009 3:40:40 PM
On Nov 10, 5:03 am, "Chris Morley" <chris.mor...@lineone.net> wrote:
> > And I let the program continue for few minutes.  It still prints "it
> > is not ready".
>
> > Any idea?
>
> Are you sure your threads are accessing the _same_ instance of class A you
> are using and not that each thread is accessing it's own thread local copy?
>
> You could test this easily by adding printfs to display "this" pointer & see
> if they match!
>
> void A::change() {
>      printf("change this=%p\n", this);
>       printf("changed!\n");
>       ready=true;
>
> }
>
> void A::doSomething() {
>      printf("doSomething this=%p\n", this);
>       while(true) {
>                  if (ready) printf("it is ready\n");
>           else printf("it is not ready\n");
>       }
>
> }
>
> If they don't print equal then you are definately using different instances.
> If they do print equal I'd need more code to see what the problem is.
>
> Hope this helps.
>
> Chris

I will give it a try later.

I believe that it is the same instance because if I restart the
program couple times, most the time, it works fine.  Hence, I believe
that it is some racing condition...or I mis-interpret "volatile".

Thanks.


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

0
Hei
11/10/2009 3:40:40 PM
On Nov 10, 8:28 am, Hei <hchan1...@gmail.com> wrote:
>          volatile bool ready;
[...
> One of the threads will call A.change(), and another thread will call
> A.doSomething().

Judging from the subject of your article and the mention of threads
you seem to assume that volatile has anything to do with threading. In
C++ it has not. The volatile keyword merely indicates that the
*compiler* should not optimize accesses to the corresponding object in
any shape. That is, the compiler will diligently put in the
appropriate read and write instructions to access the data. However,
the CPU will see that there is no synchronization directive and decide
that it doesn't need to reread or flush the cache and hence never
notice the change. Well, maybe it will notice the change at some
point, maybe it will not.

The purpose of the volatile keyword is mainly to deal with changing
memory the CPU somehow knows is changing. For example, this may apply
to memory mapped I/O hardware: the CPU will be vary careful not to
cache this. Since the compiler was careful to do what the code says
rather than trying to be smart, this will just work nicely.

When you want to communicate data between multiple threads you always
need some form of synchronization. This can be as basic as
strategically positioned memory barriers but something is needed. I
understand that other languages use e.g. 'volatile int' for things the
upcoming C++ standard will call 'std::atomic<int>' but this has not
relevance whatsoever how things in C++ are done: neither the current C+
+ standard nor the upcoming C++ standard will make any guarantees with
respect to the use of 'volatile' and threading. You may have found
that in the past sprinkling 'volatile' keywords over the code somehow
helped but this was mostly [bad] luck.


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

0
dietmar_kuehl
11/10/2009 11:13:55 PM
On 11月10日, 下午1時32分, CornedBee <wasti.r...@gmx.net> wrote:
> On Nov 10, 9:28 am, Hei <hchan1...@gmail.com> wrote:
>
>
>
> > Hi,
> >          volatilebool ready;
>
> > A::A() : ready(false) {}
>
> > A::change() {
> >      printf("changed!\n");
> >      ready=true;
>
> > }
>
> > A::doSomething() {
> >      // the actual code is not an infinite loop but very close --
> > doSomething is being called at very high frequency without a while
> > loop.
> >      while(true) {
> >          if (ready) printf("it is ready\n");
> >          else printf("it is not ready\n");
> >      }
>
> > }
>
> > One of the threads will call A.change(), and another thread will call
> > A.doSomething().
>
> The semantics ofvolatileare very specific, and they are intended to
> read and write special memory locations (e.g. memory-mapped I/O
> registers of periphery), not for thread communication.Volatileforces
> the compiler to assume that the variable can change unexpectedly, that
> simply writing or even reading it can have side effects, and thus to
> never lift it to a register or reorder/omit accesses.Volatiledoes not force the CPU(s) to do anything, though. You're
> accessing a simple variable, an ordinary memory location. The CPU,
> unlike the compiler, isn't fooled by you - it knows that no periphery
> is going to change this location. Any core therefore can, depending on
> the architecture's cache consistency model, hold the variable in its
> private cache and keep reading the cached version, never noticing that
> another core changed the memory location. What you need is atomic
> access. Only then can you reliably and portably use a variable as a
> ready flag.
> Standard C++ doesn't yet have atomic variables. But various thread
> libraries offer them.
>
> All that said, if you're on an x86, all the above doesn't mean much,
> because the architecture's cache consistency model should force the
> change to be detected pretty soon.

{ edits: quoted banner removed. please don't quote the banner. -mod }

I understand the part that "volatile" isn't a replacement for a
synchronization block.  I don't know anything about the
"architecture's cache consistency model"...but I am running my program
on a x86_64 machine.

My original idea is to make the compiler not to optimize the code by
caching my variable in a register.  I am okay that in runtime, the
core takes several sec to detect that the volatile variable has been
changed.

I was trying to avoid using mutex/lock to save some micro sec because
doSomething() is called very frequently.

So it sounds like my CPU isn't able to detect the change?


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

0
Hei
11/10/2009 11:18:59 PM
On 11月10日, 下午9時13分, "dietmar_ku...@yahoo.com"
<dietmar.ku...@gmail.com> wrote:
> On Nov 10, 8:28 am, Hei <hchan1...@gmail.com> wrote:
>
> >          volatilebool ready;
> [...
> > One of the threads will call A.change(), and another thread will call
> > A.doSomething().
>
> Judging from the subject of your article and the mention of threads
> you seem to assume thatvolatilehas anything to do with threading. In
> C++ it has not. Thevolatilekeyword merely indicates that the
> *compiler* should not optimize accesses to the corresponding object in
> any shape. That is, the compiler will diligently put in the
> appropriate read and write instructions to access the data. However,
> the CPU will see that there is no synchronization directive and decide
> that it doesn't need to reread or flush the cache and hence never
> notice the change. Well, maybe it will notice the change at some
> point, maybe it will not.
>
> The purpose of thevolatilekeyword is mainly to deal with changing
> memory the CPU somehow knows is changing. For example, this may apply
> to memory mapped I/O hardware: the CPU will be vary careful not to
> cache this. Since the compiler was careful to do what the code says
> rather than trying to be smart, this will just work nicely.
>
> When you want to communicate data between multiple threads you always
> need some form of synchronization. This can be as basic as
> strategically positioned memory barriers but something is needed. I
> understand that other languages use e.g. 'volatileint' for things the
> upcoming C++ standard will call 'std::atomic<int>' but this has not
> relevance whatsoever how things in C++ are done: neither the current C+
> + standard nor the upcoming C++ standard will make any guarantees with
> respect to the use of 'volatile' and threading. You may have found
> that in the past sprinkling 'volatile' keywords over the code somehow
> helped but this was mostly [bad] luck.
>

My confusion came after I read this article: http://www.ddj.com/cpp/184403766

I thought volatile made the compiler not to cache the variable in a
register, and so each thread would get a most updated copy.

If I understand all the post correctly, even with volatile, a variable
can be cached in a CPU's cache, and CPU somehow can figure when to
flush if the variable is changed...such change has nothing to do with
threads at all?


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

0
Hei
11/11/2009 1:24:39 PM
Hi,

> I believe that it is the same instance because if I restart the
> program couple times, most the time, it works fine.  Hence, I believe
> that it is some racing condition...or I mis-interpret "volatile".

There is new information here that it work most of the time! I assumed from
your original post that it was always broken. I'd also say then you have
some race condition.

Without more code it is difficult to suggest something concrete but I'd be
suspicious obviously of any code that writes to the bool. If that is only
change() & the constructor then are you sure the object is _always_
constructed before change() is called? Is it a static? Is it stack/heap
allocated and before _or_ after you fork the new threads... stick a printf
in the constructor. (i.e. is it possible you get the sequnce a.change();
a(); a.soSomethign()) Try wasting some time prior to the change() call so
burn so cycles in a loop or Sleep() (Windows or *nix equivalent) for 1s &
see what happens. I'm sure you have searched for accidental writes to ready.
Does it always work if you set the affinity to a single core? Try setting
ready to true in the constructor, does it print ready all the time as
expected or sometimes not ready?? Is ready only ever _written_ to in 1
thread or more?

Anyway, if you can force a change of behaviour (broken always or fixed
always) it should give you an idea where your problem actually lies.

If it is a synchronisation problem then either construct the A before going
into the threads or if that isn't possible you need to synchronise the
start - I'd suggest you use OS functions (e.g. WaitForSingleObject on
Windows) as they can freeze thread execution while they wait. Also OS is
easier than rolling your own sync.

Chris


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

0
Chris
11/11/2009 1:29:01 PM
dietmar_kuehl@yahoo.com wrote:
> Judging from the subject of your article and the mention of threads
> you seem to assume that volatile has anything to do with threading.
> In C++ it has not.

Mark Rosewater, in his many columns about designing the trading
card game Magic The Gathering, often writes that one of the worst
things a game designer can do is to confound the expectations of
players as to how something works. Here's a sample column.
<http://www.wizards.com/magic/magazine/article.aspx?x=mtgcom/daily/mr333>

Given that so many people assume that volatile data and multiple
threads work together as a simple form of synchronization, perhaps
they should.

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

0
Hyman
11/11/2009 7:02:36 PM
On 10 Nov, 21:30, Pete Becker <p...@versatilecoding.com> wrote:
> Hei wrote:
>
> > And I let the program continue for few minutes.  It still prints "it
> > is not ready".
>
> > Any idea?
>
> Does the compiler's documentation tell you that this will work? The
> language definition does not require volatile to impose synchronization
> on a variable that's accessed from multiple threads. If one thread is
> running on one CPU and the other thread on another CPU, writing from one
> thread writes to that CPU's cache; the other CPU has its own cache, and
> won't see that change until the write is flushed to main memory and the
> previously read value is replaced from main memory. To make that happen,
> you need synchronization; typically through a mutex or a condition variable.

This would be a good answer except for the ouput.
The two threads show interleaved writes to a stdout. This is either
unsupported and he just got lucky or the I/O susbsystem is protecting
itself with mutexes hence I am leaning towards the idea that the OP
hasn't actually done what he says that he has done.


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

0
Nick
11/11/2009 7:04:01 PM
Hyman Rosen wrote:
> dietmar_kuehl@yahoo.com wrote:
>> Judging from the subject of your article and the mention of threads
>> you seem to assume that volatile has anything to do with threading.
>> In C++ it has not.
>
> Mark Rosewater, in his many columns about designing the trading
> card game Magic The Gathering, often writes that one of the worst
> things a game designer can do is to confound the expectations of
> players as to how something works. Here's a sample column.
> <http://www.wizards.com/magic/magazine/article.aspx?x=mtgcom/daily/mr333>
>
> Given that so many people assume that volatile data and multiple
> threads work together as a simple form of synchronization, perhaps
> they should.

They do on some systems (as an extension).

It would be EXTREMELY expensive on other systems, where volatile is 
actually used as originally intended - for accessing memory mapped 
devices. Would you like a 128-way Itanium system do invalidate all 
on-chip caches, just in case?


Bo Persson



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

0
Bo
11/12/2009 8:19:28 PM
"Hei" <hchan1980@gmail.com>

> My confusion came after I read this article: 
> http://www.ddj.com/cpp/184403766

Did you actually read it beyond the title?
It is about supplementing the code using sync with type system checks.

It neve claims volatile would be a replacement to using mutex and locking.

> I thought volatile made the compiler not to cache the variable in a
> register, and so each thread would get a most updated copy.

Then why class Counter in the article has that Mutex? And the other shown 
classes?

> If I understand all the post correctly, even with volatile, a variable
> can be cached in a CPU's cache, and CPU somehow can figure when to
> flush if the variable is changed...such change has nothing to do with
> threads at all?

In short, volatile has little to o with threading itself.

http://software.intel.com/en-us/blogs/2007/11/30/volatile-almost-useless-for-multi-threaded-programming/

AA just uses it as MAGIC to detect imprer  access to a shared variable right 
at compare time.


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

0
Balog
11/16/2009 3:05:03 PM
Balog Pal wrote:
> (...)
> In short, volatile has little to o with threading itself.
> 
> http://software.intel.com/en-us/blogs/2007/11/30/volatile-almost-useless-for-multi-threaded-programming/ 
> 

I would like to highlight one point from the article:

[quote volatile-almost-useless-for-multi-threaded-programming]
Now consider issue (2). Sometimes programmers think of volatile as
turning off optimization of volatile accesses. That's largely true in
practice. But that's only the volatile accesses, not the non-volatile
ones. Consider this fragment:

     volatile int Ready;
     int Message[100];
     void foo( int i ) {
         Message[i/10] = 42;
         Ready = 1;
     }
It's trying to do something very reasonable in multi-threaded
programming: write a message and then send it to another thread. The
other thread will wait until Ready becomes non-zero and then read
Message. Try compiling this with "gcc -O2 -S" using gcc 4.0, or icc.
Both will do the store to Ready first, so it can be overlapped with the
computation of i/10. The reordering is not a compiler bug. It's an
aggressive optimizer doing its job.

[/quote]

I personally never thought of this problem -- guess I'll have to do
another grep on our codebase for volatile.
Just another point on the list to check before I can enable
optimizations in the release build. *Sigh* :)

br,
Martin

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

0
Martin
11/17/2009 7:48:09 AM
On Nov 11, 11:24 am, Hei <hchan1...@gmail.com> wrote:
> My confusion came after I read this article:http://www.ddj.com/cpp/184403766
>
> I thought volatile made the compiler not to cache the variable in a
> register, and so each thread would get a most updated copy.
>
> If I understand all the post correctly, even with volatile, a variable
> can be cached in a CPU's cache, and CPU somehow can figure when to
> flush if the variable is changed...such change has nothing to do with
> threads at all?

Again, as others else-thread have mentioned, volatile was intended for
memory mapped IO, (and signal handlers, and communication between
setjump and longjump (sp)). The article http://www.ddj.com/cpp/184403766
is simply wrong. Very wrong. For a full description on why volatile is
useless in C++ as a portable threading construct, I point you to my
favorite (and correct) paper on the subject:

C++ and the Perils of Double-Checked Locking
http://www.aristeia.com/Papers/DDJ_Jul_Aug_2004_revised.pdf

The short version is that most compiler writers have decided that they
can break the "as if" rule between threads without correct
synchronization. The standard doesn't mention threads, so it's not
like it's breaking the standard. It's also the correct decision in
terms of the spirit and intent of the C++ standard (don't pay for what
you don't use, cost competitive with assembly, volatile is for memory
mapped IO).


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

0
Joshua
11/17/2009 3:01:49 PM
On Nov 16, 1:05 pm, "Balog Pal" <p...@lib.hu> wrote:
> "Hei" <hchan1...@gmail.com>
> > My confusion came after I read this article:
> >http://www.ddj.com/cpp/184403766
>
> Did you actually read it beyond the title?

The better question is did \you\ actually read it beyond the title.

> It is about supplementing the code using sync with type system checks.
> It neve claims volatile would be a replacement to using mutex and locking.

Yes, it does.

Quoting ddj article
> Although both C and C++ Standards are conspicuously silent when it comes to threads, they do make a little concession to multithreading, in the form of the volatile keyword.

> Just like its better-known counterpart const, volatile is a type modifier. It's intended to be used in conjunction with variables that are accessed and modified in different threads. Basically, without volatile, either writing multithreaded programs becomes impossible, or the compiler wastes vast optimization opportunities. An explanation is in order.

The article goes on to suggest that the following is a
"correct" (albeit inefficient and slow), condition variable in multi-
threaded situations:

class Gadget
{
public:
     void Wait()
     {    while (!flag_)
             Sleep(1000); // sleeps for 1000 milliseconds
     }
     void Wakeup() { flag_ = true; }
     ...
private:
     volatile bool flag_;
};

Quote ddj article (in the context of flag_ not being volatile):
> Suppose the compiler figures out that Sleep(1000) is a call into an external library that cannot possibly modify the member variable flag_. Then the compiler concludes that it can cache flag_ in a register and use that register instead of accessing the slower on-board memory. This is an excellent optimization for single-threaded code, but in this case, it harms correctness: after you call Wait for some Gadget object, although another thread calls Wakeup, Wait will loop forever. This is because the change of flag_ will not be reflected in the register that caches flag_. The optimization is too ... optimistic. Caching variables in registers is a very valuable optimization that applies most of the time, so it would be a pity to waste it. C and C++ give you the chance to explicitly disable such caching. If you use the volatile modifier on a variable, the compiler won't cache that variable in registers � each access will hit the actual memory location of that variable. So all y
!
  ou have to do to make Gadget's Wait/Wakeup combo work is to qualify flag_ appropriately:
[Insert code fragment with volatile flag_]

That piece of code when Wait and Wakeup are called from different
threads, despite whatever volatile qualification, is not correct
according to the C++ standard (as it doesn't mention threads). If it
was correct, that would be against the spirit of the C and C++
standard: (1- Volatile is for memory mapped IO, signal handlers, and
setjump longjump (sp). 2- Cost competitive with assembly. 3- Don't pay
for what you don't use.). It will not be correct in C++0x, which
includes descriptions of threading. Finally, according to the standard
threading library POSIX, it's actually wrong. (However, using the
other standard threading library, win32, the code fragment may be
correct with volatile. Go find a microsoft newsgroup or use the msdn
webpages for further details.)


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

0
Joshua
11/17/2009 8:13:37 PM
{ Top-posting converted to bottom-posting by mod.
  Please follow the convention in this group. -mod }

On Tuesday, November 17, 2009 6:13:37 PM UTC-8, Joshua Maurice wrote:
> On Nov 16, 1:05 pm, "Balog Pal" <p...@lib.hu> wrote:
> > "Hei" <hchan1...@gmail.com>
> > > My confusion came after I read this article:
> > >http://www.ddj.com/cpp/184403766
> >
> > Did you actually read it beyond the title?
> 
> The better question is did \you\ actually read it beyond the title.
> 
> > It is about supplementing the code using sync with type system checks.
> > It neve claims volatile would be a replacement to using mutex and locking.
> 
> Yes, it does.
> 
> Quoting ddj article
> > Although both C and C++ Standards are conspicuously silent when it comes to threads, they do make a little concession to multithreading, in the form of the volatile keyword.
> 
> > Just like its better-known counterpart const, volatile is a type modifier. It's intended to be used in conjunction with variables that are accessed and modified in different threads. Basically, without volatile, either writing multithreaded programs becomes impossible, or the compiler wastes vast optimization opportunities. An explanation is in order.
> 
> The article goes on to suggest that the following is a
> "correct" (albeit inefficient and slow), condition variable in multi-
> threaded situations:
> 
> class Gadget
> {
> public:
>      void Wait()
>      {    while (!flag_)
>              Sleep(1000); // sleeps for 1000 milliseconds
>      }
>      void Wakeup() { flag_ = true; }
>      ...
> private:
>      volatile bool flag_;
> };
> 
> Quote ddj article (in the context of flag_ not being volatile):
> > Suppose the compiler figures out that Sleep(1000) is a call into an external library that cannot possibly modify the member variable flag_. Then the compiler concludes that it can cache flag_ in a register and use that register instead of accessing the slower on-board memory. This is an excellent optimization for single-threaded code, but in this case, it harms correctness: after you call Wait for some Gadget object, although another thread calls Wakeup, Wait will loop forever. This is because the change of flag_ will not be reflected in the register that caches flag_. The optimization is too ... optimistic. Caching variables in registers is a very valuable optimization that applies most of the time, so it would be a pity to waste it. C and C++ give you the chance to explicitly disable such caching. If you use the volatile modifier on a variable, the compiler won't cache that variable in registers � each access will hit the actual memory location of that variable. So al
 l
>  you have to do to make Gadget's Wait/Wakeup combo work is to qualify flag_ appropriately:
> [Insert code fragment with volatile flag_]
> 
> That piece of code when Wait and Wakeup are called from different
> threads, despite whatever volatile qualification, is not correct
> according to the C++ standard (as it doesn't mention threads). If it
> was correct, that would be against the spirit of the C and C++
> standard: (1- Volatile is for memory mapped IO, signal handlers, and
> setjump longjump (sp). 2- Cost competitive with assembly. 3- Don't pay
> for what you don't use.). It will not be correct in C++0x, which
> includes descriptions of threading. Finally, according to the standard
> threading library POSIX, it's actually wrong. (However, using the
> other standard threading library, win32, the code fragment may be
> correct with volatile. Go find a microsoft newsgroup or use the msdn
> webpages for further details.)

Sorry to bring back this old thread.

As most of you pointed out, C++ Standard (before C11) doesn't know
anything about thread; hence, volatile has nothing to do with thread.

I just want to understand whether this statement from Modern C++ Design
(by Andrei Alexandrescu) is wrong:
"C++ provides the volatile type modifier, with which you should qualify
each variable that you share with multiple threads."

Although it doesn't explicitly suggest volatile do something about
multithreading, it seems to me that it implicitly suggests so.

If not, how should I interpret the statement?

Thanks in advance.

-- 
      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]
0
hchan1980
11/2/2012 6:25:16 PM
On 2012-11-02 18:25:16 +0000, hchan1980@googlemail.com said:

>
> I just want to understand whether this statement from Modern C++
> Design (by Andrei Alexandrescu) is wrong:
> "C++ provides the volatile type modifier, with which you should
> qualify each variable that you share with multiple threads."
>
> Although it doesn't explicitly suggest volatile do something about
> multithreading, it seems to me that it implicitly suggests so.
>
> If not, how should I interpret the statement?
>

Interpret it as wrong.

-- 
   Pete


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

0
Pete
11/3/2012 3:19:39 PM
Reply:

Similar Artilces:

program that compiles in C compiler but not in C++ compiler
Hi, I need a small program that compiles in C compiler but not in C++ compiler. Thx in advans, Karthik Balaguru KBG <karthik.balaguru@lntinfotech.com> wrote: > I need a small program that compiles in C compiler but not in C++ > compiler. No problem, just send $10 to paypal@zevv.nl and I'll do your homework for you. -- :wq ^X^Cy^K^X^C^C^C^C KBG said: > Hi, > > I need a small program that compiles in C compiler but not in C++ > compiler. Can you think of any syntactic differences between C and C++? For example, what about keywords? They are very, very sen...

Are sun studio C/C++ compilers and Forte C/C++ compilers same ??
Is there any difference between sun studio compilers and forte compilers??? or the names have been changed??? In article <1145338052.955429.256610@v46g2000cwv.googlegroups.com>, "ameya_agnihotri" <ameyaagnihotri22@gmail.com> writes: > Is there any difference between sun studio compilers and forte > compilers??? > or the names have been changed??? One of many name changes in the product's history (including amongst others, Java somethingortheother, Workshop, Proworks/Teamworks, and probably more I've forgotten). Of course, the versions and features cha...

Writing a C/C++ compiler in C++
I've been thinking of writing a C++ compiler in C++ over the next several years, and I was wondering what's changed in writing a compiler? I've been pouring over these groups and there seems to be a lot of tools for starting but is the modern process still the same? As far as I understand it you write a lexer that tokenizes all the symbols, then write a parser that parses all of the tokens, then walks the parse tree to generate the asm or IL that gets shoved to the backend. So it seemed straightforward except that C++ isn't a LALR(1) grammer that Bison or Byacc accepts. Does ...

Will C pgm compile on C++ compiler?
I had C programming in school years ago and would like to play with it again. When I go online I only seem to be able to find C++ compilers. I know that C++ is object oriented, whereas C is not. I can get a good price on Visual C++ 6.0. Is there a way to run native C programs on a C++ compiler? Thanks, Ken [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ] "Ken Applequist" <apple07840@yahoo.com> wrote in message news:<Sh%1d.4320$F75.1229@trndny01>... > I had C programming in school ...

compiling c code but libraries are compiled in c++
hi, We have written cunit code for testing some APIs. defination of those APIs are in c++ and .so library is created of them. when I compile my cunit code it gets compiled successfully but while liking it gives undefined reference to symbol. can anyone help me in this matter. Regards Sumit Shrivastava On 29 May 2007 04:11:14 -0700 sumit <sumit.shrivastava09@gmail.com> wrote: | We have written cunit code for testing some APIs. defination of | those APIs are in c++ and .so library is created of them. when I | compile my cunit code it gets compiled successf...

Could I compile "c" source with a C++ compiler (Forte C++ Update 2)?
Does Forte C++ Update 2 compiles C source code in ANSI C as same as Forte C udpate 2 does? Jacob, Park <bluejacob@empal.com> wrote: > Does Forte C++ Update 2 compiles C source code in ANSI C as same as > Forte C udpate 2 does? If you're asking whether "CC" will compile the same code as "cc", then the answer is no. This is true for ANY standard-compliant c++ compiler (compilers with different "language mode" like gcc don't count as a single compiler for this description). However, usually one can make C code "compilable" by C++ co...

Re: Will C pgm compile on C++ compiler?
Ken Applequist wrote: > I had C programming in school years ago and would like to play with it > again. When I go online I only seem to be able to find C++ compilers. I know > that C++ is object oriented, whereas C is not. I can get a good price on > Visual C++ 6.0. Is there a way to run native C programs on a C++ compiler? Several authors implied that a C++ compiler can compile C programs. This is only correct with some restrictions. For example, you can obviously not use C++ keywords as identifiers. For example, the following is a legal C program but will fail using C++: in...

commercial c compilers vs free c compilers
what are the benefits in using commercial compilers like intel, greenhill or portland compared to free c compiles like gcc, lcc, tcc, TenDRA, sun and others? geletine wrote: > what are the benefits in using commercial compilers like intel, > greenhill or portland compared to free c compiles like gcc, lcc, tcc, > TenDRA, sun and others? > <mostly non-topical> As we have no idea of your interests, potential benefits may not be meaningful in your projects. More than one of these commercial compilers is more efficient about vectorization, although gcc is closing the gap. <...

link a c compiled application with a c++ compiled library ?
Hi, I've searched nearly one hour for this but found nothing usefull :-/ So my question is simple : Is it possible to link a c compiled application with a C++ compiled library ?? If yes, how would it possible.. (I guess this would be indirectly posible by using some wrapper around the c++ library, but I'm aboslutely not wanting to do that in my case, well at least if I have to write that wrapper manually myself). I looked at gcc,g++ man pages, gcc online documentation, .. but can't even find a beginning of info related to that :-/ Thank you if you can help me. Regards, ...

C++ to C compiler
Hi all. I've made a tool which compiles a C++-like language and produces good old C99 (with some gcc extensions in certain cases). Maybe it can get in the free-compilers list. It is interesting because by studing the -readable- generated C code you an understand how C++ features are implemented. It's also easy to add new features and extensions. The URL is: http://students.ceid.upatras.gr/~sxanth/lwc/index.html It is only known to work on a gcc/gnu-libc system and it is definitelly BETA. The parser is written entirely in C. I'm currently working on a builtin regular expressio...

C compiles, C++ Does Not
I recently installed DJGPP on my system. There was no problem during the install. However I can compile C programs without any problems but when I try to compile a C++ program I get a long list of error messages and the file will not compile. Can anyone suggest what the problem might be ? On Thu, 15 Apr 2004 03:35:45 GMT in comp.os.msdos.djgpp, charlesreed@eatel.net (Charles Reed) wrote: > I recently installed DJGPP on my system. There was no >problem during the install. However I can compile C programs without >any problems but when I try to compile a C++ program I get a...

Compiling C into C++
I'm trying to include a C header file from an external library in my C+ + program but when I compile I get the following error: error: expected unqualified-id before 'private' error: abstract declarator 'void*' used as declaration error: expected ';' before 'private' It didn't take me long to figure out that the offending C header file uses a variable with the name "private". I've reproduced the problem as follows: /* -------- a.h - the C header file */ #ifndef TEST_H #define TEST_H struct s { void *private; }; #endif /* -------- end...

C/C++ compiler
Exceptionally would need to build a prog. executable to run in a 16bit environment (MS-DOS). What a compiler (for experience), that of setting options can generate executables in a 16bit not protected environment ? That is a compiler that can be run under WinXP and genres just a 16bit executable? I think it is called a cross-compiler! Obviously, free downloadable ... Thanks in advance. ostia schrieb: > Exceptionally would need to build a prog. executable to run > in a 16bit environment (MS-DOS). > What a compiler (for experience), that of setting > options can generate executa...

which c/c++ compiler?
Hi all, I'd like to know if Microsoft Visual Studio .NET 2003 can be used for real-time applications. I'm a new user of Matlab and I'm trying to use Simulink and Real-Time Windows Target for acquiring data coming from an accelerometer. I've read in RTWT tutorial that is recommended the use of Microsoft Visual C/C++ or Watcom compiler..... Bye! Hi, Read the solution give at the following link, http://www.mathworks.com/support/solutions/data/1-1BRI9.html?solution=1-1BRI9 Bye! On Sun, 05 Sep 2004 12:32:21 GMT, Alessandra wrote: >Hi all, >I'd like to know if Microso...

Web resources about - volatile is ignored by my compiler? - comp.lang.c++.moderated

Compiler - Wikipedia, the free encyclopedia
... , or external linking . The most common reason for wanting to transform source code is to create an executable program. The name "compiler" ...

Compiler - Wikipedia, the free encyclopedia
"Compile" and "compiling" redirect here. For the software company, see Compile (publisher) . For other uses, see Compilation . This article has ...

Facebook Open-Sources HipHop PHP Compiler Software
Earlier this morning, Facebook officially made their new PHP “compiler,” called HipHop, available as open source software. In the blog post by ...

Art in the Age of Matter Compilers
jurvetson posted a photo: Sheba may be the harbinger of art in the digital age — a mathematical sculptor with digital matter. She manipulates ...

Interpreters and Compilers (Bits and Bytes, Episode 6) - YouTube
This animation explains the difference between interpreters and compilers. It is from Episode 6 of the classic 1983 television series, Bits and ...

Typesafe cofounder forking Scala compiler
The main contributor to the Scala compiler, Paul Phillips, has announced on GitHub that he is forking the compiler to “fix some of the innumerable ...

Does Apple's new developer agreement ban Adobe's Flash-to-iPhone compiler?
Given that any kind of formal truce between Apple and Adobe was essentially blown out of the water by Steve Job's very public slating of Flash ...

Apple seeds devs with Safari 5.2 for Lion, Xcode 4.4 with new LLVM compiler
... to the general public this summer. Among the new features: According to Apple, Xcode 4.4 includes an editor for Collada 3D files, compiler support ...

NVIDIA and Continuum Analytics Announce NumbaPro, A Python CUDA Compiler
... are announcing that they are bringing Python support to CUDA. Specifically, Continuum Analytics’ will be introducing a new Python CUDA compiler, ...

IntelliJ Releases IDEA 12, Brings Improved UI, New Compiler Mode, Android UI Designer, And More
I'm not going to pretend to be a developer here, and I'll openly admit that the bulk of what IDEA 12 does is over my head. However, I do understand ...

Resources last updated: 2/2/2016 8:54:00 PM