Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.programming.threads > #1781 > unrolled thread

Re: forcing the compiler to reload from memory with c++0x

Started byAlexander Terekhov <terekhov@web.de>
First post2011-02-01 14:17 +0100
Last post2011-02-01 13:51 +0000
Articles 10 — 4 participants

Back to article view | Back to comp.programming.threads

This discussion starts older than the indexed window; earlier articles aren't shown. The article labeled Started by below is the oldest one visible, not the original post.


Contents

  Re: forcing the compiler to reload from memory with c++0x Alexander Terekhov <terekhov@web.de> - 2011-02-01 14:17 +0100
    Re: forcing the compiler to reload from memory with c++0x Alexander Terekhov <terekhov@web.de> - 2011-02-02 14:45 +0100
      Re: forcing the compiler to reload from memory with c++0x Dmitriy Vyukov <dvyukov@gmail.com> - 2011-02-02 07:02 -0800
        Re: forcing the compiler to reload from memory with c++0x Alexander Terekhov <terekhov@web.de> - 2011-02-02 16:33 +0100
    Re: forcing the compiler to reload from memory with c++0x Alexander Terekhov <terekhov@web.de> - 2011-02-01 16:32 +0100
      Re: forcing the compiler to reload from memory with c++0x Alexander Terekhov <terekhov@web.de> - 2011-02-02 12:13 +0100
        Re: forcing the compiler to reload from memory with c++0x Dmitriy Vyukov <dvyukov@gmail.com> - 2011-02-02 04:54 -0800
      Re: forcing the compiler to reload from memory with c++0x Dmitriy Vyukov <dvyukov@gmail.com> - 2011-02-01 21:02 -0800
      Re: forcing the compiler to reload from memory with c++0x Joshua Maurice <joshuamaurice@gmail.com> - 2011-02-01 15:19 -0800
    Re: forcing the compiler to reload from memory with c++0x Anthony Williams <anthony.ajw@gmail.com> - 2011-02-01 13:51 +0000

#1781 — Re: forcing the compiler to reload from memory with c++0x

FromAlexander Terekhov <terekhov@web.de>
Date2011-02-01 14:17 +0100
SubjectRe: forcing the compiler to reload from memory with c++0x
Message-ID<4D480800.1C5132D7@web.de>
Anthony Williams wrote:
[...]
> You can of course make your atomic variables volatile too, and then they
> DO become observable behaviour.

Observable as in what? Memory mapped I/O variables and signal handlers
aside, you can't mean debuggers and/or asm listings. The following
programs

int main() {
  volatile int i;
  // volatile write = has no observable effect
  i = 1;
  // volatile read = has no observable effect
  int n = i;
  // output: 1
  std::cout << n;
}

int main() {
  // output: 1
  std::cout << 1;
}

can be translated into the same executable code.

regards,
alexander.

[toc] | [next] | [standalone]


#1789

FromAlexander Terekhov <terekhov@web.de>
Date2011-02-02 14:45 +0100
Message-ID<4D495FE0.ED8A251E@web.de>
In reply to#1781
Dmitriy Vyukov wrote:
[...]
> Alexander, you are inconsistent here.
> Why can't printf() output go to nowhere on its own in the first place?
> Abstract output is basically the same as abstract memory accesses on
> abstract machine, no? And what is that abstract "standard output"
> device or file? If we go down to that formal hair-splitting level,
> then I believe we won't conclude anything useful. For example, is
> there dynamic memory? Well, I'm not sure. Is zero bytes of dynamic
> memory still dynamic memory? I guess it's nothing.
> If you want, there is always an implementation. And it's possible to
> loosely define such group of implementations as "sane industrial
> implementations". And in that context volatile access indeed means the
> most natural memory access instruction in generated code (MOV, LD or
> whatever). And that is observable. And that is what Anthony meant, I
> think.

Stop abstracting into absurdity. "MOV, LD or whatever" are not
externally observable in the case of

int main() {
  volatile int i;
  // volatile write = has no observable effect
  i = 1;
  // volatile read = has no observable effect
  int n = i;
}

because the above program is the same as

int main() {
}

for any reasonable observer of the outcome.

regards,
alexander.

[toc] | [prev] | [next] | [standalone]


#1801

FromDmitriy Vyukov <dvyukov@gmail.com>
Date2011-02-02 07:02 -0800
Message-ID<ecac5840-7645-478c-86b8-1f195a372860@g10g2000vbv.googlegroups.com>
In reply to#1789
On 2 фев, 16:45, Alexander Terekhov <terek...@web.de> wrote:
> Dmitriy Vyukov wrote:
>
> [...]
>
> > Alexander, you are inconsistent here.
> > Why can't printf() output go to nowhere on its own in the first place?
> > Abstract output is basically the same as abstract memory accesses on
> > abstract machine, no? And what is that abstract "standard output"
> > device or file? If we go down to that formal hair-splitting level,
> > then I believe we won't conclude anything useful. For example, is
> > there dynamic memory? Well, I'm not sure. Is zero bytes of dynamic
> > memory still dynamic memory? I guess it's nothing.
> > If you want, there is always an implementation. And it's possible to
> > loosely define such group of implementations as "sane industrial
> > implementations". And in that context volatile access indeed means the
> > most natural memory access instruction in generated code (MOV, LD or
> > whatever). And that is observable. And that is what Anthony meant, I
> > think.
>
> Stop abstracting into absurdity. "MOV, LD or whatever" are not
> externally observable in the case of
>
> int main() {
>   volatile int i;
>   // volatile write = has no observable effect
>   i = 1;
>   // volatile read = has no observable effect
>   int n = i;
>
> }
>
> because the above program is the same as
>
> int main() {
>
> }
>
> for any reasonable observer of the outcome.

I can observe it in disassembler or by timing the program. A compiler
can't do any assumptions on how I'm going to observe it.

--
Dmitriy V'jukov

[toc] | [prev] | [next] | [standalone]


#1828

FromAlexander Terekhov <terekhov@web.de>
Date2011-02-02 16:33 +0100
Message-ID<4D49795A.6C47C280@web.de>
In reply to#1801
Dmitriy Vyukov wrote:
> 
> On 2 фев, 16:45, Alexander Terekhov <terek...@web.de> wrote:
> > Dmitriy Vyukov wrote:
> >
> > [...]
> >
> > > Alexander, you are inconsistent here.
> > > Why can't printf() output go to nowhere on its own in the first place?
> > > Abstract output is basically the same as abstract memory accesses on
> > > abstract machine, no? And what is that abstract "standard output"
> > > device or file? If we go down to that formal hair-splitting level,
> > > then I believe we won't conclude anything useful. For example, is
> > > there dynamic memory? Well, I'm not sure. Is zero bytes of dynamic
> > > memory still dynamic memory? I guess it's nothing.
> > > If you want, there is always an implementation. And it's possible to
> > > loosely define such group of implementations as "sane industrial
> > > implementations". And in that context volatile access indeed means the
> > > most natural memory access instruction in generated code (MOV, LD or
> > > whatever). And that is observable. And that is what Anthony meant, I
> > > think.
> >
> > Stop abstracting into absurdity. "MOV, LD or whatever" are not
> > externally observable in the case of
> >
> > int main() {
> > Â  volatile int i;
> > Â  // volatile write = has no observable effect
> > Â  i = 1;
> > Â  // volatile read = has no observable effect
> > Â  int n = i;
> >
> > }
> >
> > because the above program is the same as
> >
> > int main() {
> >
> > }
> >
> > for any reasonable observer of the outcome.
> 
> I can observe it in disassembler or by timing the program. A compiler
> can't do any assumptions on how I'm going to observe it.

Can you really point out a chapter and verse guaranteeing that int
main() {} is faster than int main() { volatile int i = 1; int n = i; }?
As I told: disassembler is irrelevant.

regards,
alexander.

[toc] | [prev] | [next] | [standalone]


#1796

FromAlexander Terekhov <terekhov@web.de>
Date2011-02-01 16:32 +0100
Message-ID<4D482797.CBE41A86@web.de>
In reply to#1781
Anthony Williams wrote:
> 
> Alexander Terekhov <terekhov@web.de> writes:
> 
> > Anthony Williams wrote:
> > [...]
> >> You can of course make your atomic variables volatile too, and then they
> >> DO become observable behaviour.
> >
> > Observable as in what? Memory mapped I/O variables and signal handlers
> > aside, you can't mean debuggers and/or asm listings. The following
> > programs
> 
> The C++ Standard defines "observable behaviour" to be the set of
> accesses to volatile variables and I/O performed by the program.
> 
> The only requirement on a compiled program is that it produce the same
> set of observable behaviour as that required by the abstract machine,
> which includes accesses to volatile variables.
> 
> How you are supposed to observe the accesses to volatile variables is
> not specified.

Yet you call it observable? <chuckles>

> 
> > int main() {
> >   volatile int i;
> >   // volatile write = has no observable effect
> >   i = 1;
> >   // volatile read = has no observable effect
> >   int n = i;
> >   // output: 1
> >   std::cout << n;
> > }
> >
> > int main() {
> >   // output: 1
> >   std::cout << 1;
> > }
> >
> > can be translated into the same executable code.
> 
> FYI, gcc doesn't treat them the same, even with -O3: the first gets
> translated to a store of 1 to a stack variable followed by a load from
> that stack variable into a register, then a call to write that to
> cout. The second just gets translated into a load of 1 into a register,
> then a call to write that to cout. If you omit the "volatile" from the
> first example then it is translated the same as the second.

The gcc' utter stupidity doesn't prove anything. 

regards,
alexander.

[toc] | [prev] | [next] | [standalone]


#1814

FromAlexander Terekhov <terekhov@web.de>
Date2011-02-02 12:13 +0100
Message-ID<4D493C5C.83CA38C@web.de>
In reply to#1796
Dmitriy Vyukov wrote:
> 
> On 1 фев, 18:32, Alexander Terekhov <terek...@web.de> wrote:
> > Anthony Williams wrote:
> >
> > > Alexander Terekhov <terek...@web.de> writes:
> >
> > > > Anthony Williams wrote:
> > > > [...]
> > > >> You can of course make your atomic variables volatile too, and then they
> > > >> DO become observable behaviour.
> >
> > > > Observable as in what? Memory mapped I/O variables and signal handlers
> > > > aside, you can't mean debuggers and/or asm listings. The following
> > > > programs
> >
> > > The C++ Standard defines "observable behaviour" to be the set of
> > > accesses to volatile variables and I/O performed by the program.
> >
> > > The only requirement on a compiled program is that it produce the same
> > > set of observable behaviour as that required by the abstract machine,
> > > which includes accesses to volatile variables.
> >
> > > How you are supposed to observe the accesses to volatile variables is
> > > not specified.
> >
> > Yet you call it observable? <chuckles>
> 
> Does it differ from printf() in essence?

If a program redirects printf() output to dev/null and compiler is able
to detect such redirection then printf() can be optimized away just like
the use of volatile when it has nothing to do with MMIO, signal
handlers, setjmp/longjmp. 

regards,
alexander.

[toc] | [prev] | [next] | [standalone]


#1843

FromDmitriy Vyukov <dvyukov@gmail.com>
Date2011-02-02 04:54 -0800
Message-ID<e065a7dd-2251-4568-b914-e3e5dc7269aa@x1g2000yqb.googlegroups.com>
In reply to#1814
On 2 фев, 14:13, Alexander Terekhov <terek...@web.de> wrote:
> Dmitriy Vyukov wrote:
>
> > On 1 фев, 18:32, Alexander Terekhov <terek...@web.de> wrote:
> > > Anthony Williams wrote:
>
> > > > Alexander Terekhov <terek...@web.de> writes:
>
> > > > > Anthony Williams wrote:
> > > > > [...]
> > > > >> You can of course make your atomic variables volatile too, and then they
> > > > >> DO become observable behaviour.
>
> > > > > Observable as in what? Memory mapped I/O variables and signal handlers
> > > > > aside, you can't mean debuggers and/or asm listings. The following
> > > > > programs
>
> > > > The C++ Standard defines "observable behaviour" to be the set of
> > > > accesses to volatile variables and I/O performed by the program.
>
> > > > The only requirement on a compiled program is that it produce the same
> > > > set of observable behaviour as that required by the abstract machine,
> > > > which includes accesses to volatile variables.
>
> > > > How you are supposed to observe the accesses to volatile variables is
> > > > not specified.
>
> > > Yet you call it observable? <chuckles>
>
> > Does it differ from printf() in essence?
>
> If a program redirects printf() output to dev/null and compiler is able
> to detect such redirection then printf() can be optimized away just like
> the use of volatile when it has nothing to do with MMIO, signal
> handlers, setjmp/longjmp.

Alexander, you are inconsistent here.
Why can't printf() output go to nowhere on its own in the first place?
Abstract output is basically the same as abstract memory accesses on
abstract machine, no? And what is that abstract "standard output"
device or file? If we go down to that formal hair-splitting level,
then I believe we won't conclude anything useful. For example, is
there dynamic memory? Well, I'm not sure. Is zero bytes of dynamic
memory still dynamic memory? I guess it's nothing.
If you want, there is always an implementation. And it's possible to
loosely define such group of implementations as "sane industrial
implementations". And in that context volatile access indeed means the
most natural memory access instruction in generated code (MOV, LD or
whatever). And that is observable. And that is what Anthony meant, I
think.

--
Dmitriy V'jukov

[toc] | [prev] | [next] | [standalone]


#1825

FromDmitriy Vyukov <dvyukov@gmail.com>
Date2011-02-01 21:02 -0800
Message-ID<90c4d6f1-c539-4fdc-9b20-2cc6bc92dbe4@z20g2000yqe.googlegroups.com>
In reply to#1796
On 1 фев, 18:32, Alexander Terekhov <terek...@web.de> wrote:
> Anthony Williams wrote:
>
> > Alexander Terekhov <terek...@web.de> writes:
>
> > > Anthony Williams wrote:
> > > [...]
> > >> You can of course make your atomic variables volatile too, and then they
> > >> DO become observable behaviour.
>
> > > Observable as in what? Memory mapped I/O variables and signal handlers
> > > aside, you can't mean debuggers and/or asm listings. The following
> > > programs
>
> > The C++ Standard defines "observable behaviour" to be the set of
> > accesses to volatile variables and I/O performed by the program.
>
> > The only requirement on a compiled program is that it produce the same
> > set of observable behaviour as that required by the abstract machine,
> > which includes accesses to volatile variables.
>
> > How you are supposed to observe the accesses to volatile variables is
> > not specified.
>
> Yet you call it observable? <chuckles>

Does it differ from printf() in essence?

--
Dmitriy V'jukov

[toc] | [prev] | [next] | [standalone]


#1841

FromJoshua Maurice <joshuamaurice@gmail.com>
Date2011-02-01 15:19 -0800
Message-ID<1fff7f23-005c-4f0a-9a28-1566bd1da544@o7g2000prn.googlegroups.com>
In reply to#1796
On Feb 1, 7:32 am, Alexander Terekhov <terek...@web.de> wrote:
> Anthony Williams wrote:
> > The C++ Standard defines "observable behaviour" to be the set of
> > accesses to volatile variables and I/O performed by the program.
>
> > The only requirement on a compiled program is that it produce the same
> > set of observable behaviour as that required by the abstract machine,
> > which includes accesses to volatile variables.
>
> > How you are supposed to observe the accesses to volatile variables is
> > not specified.
>
> Yet you call it observable? <chuckles>

I'm pretty sure the C and C++ standards are phrased such that a
conforming implementation could compile the code to whatever target
language entirely ignoring the volatile keyword. Yes volatile reads
and writes are observable behavior, but what "observable behavior"
means is entirely platform specific.

One of volatile's major purposes is a hook to provide MMIO, which is
inherently platform specific. Talking about volatile MMIO and memory
reads and writes observable behavior in terms of the C or C++ standard
is silly. You need to look at the platform specs at that point.

> > > int main() {
> > >   volatile int i;
> > >   // volatile write = has no observable effect
> > >   i = 1;
> > >   // volatile read = has no observable effect
> > >   int n = i;
> > >   // output: 1
> > >   std::cout << n;
> > > }
>
> > > int main() {
> > >   // output: 1
> > >   std::cout << 1;
> > > }
>
> > > can be translated into the same executable code.
>
> > FYI, gcc doesn't treat them the same, even with -O3: the first gets
> > translated to a store of 1 to a stack variable followed by a load from
> > that stack variable into a register, then a call to write that to
> > cout. The second just gets translated into a load of 1 into a register,
> > then a call to write that to cout. If you omit the "volatile" from the
> > first example then it is translated the same as the second.
>
> The gcc' utter stupidity doesn't prove anything.

I don't think that this is utterly stupid.

First, as mentioned above, it's was intended in part to be a hook for
platform specific MMIO operations. Perhaps the way gcc compiles it
down is required for MMIO on that platform. (From my knowledge -
unlikely. James Kanze has mentioned that volatile alone is not
sufficient for MMIO on a large number of desktop and server
platforms.)

Second, volatile still has purposes besides MMIO operations. It's
other two original purposes is communication with signal handlers and
communication across setjump longjump nonsense. What gcc does with
volatile could be explained in terms of that as well.

[toc] | [prev] | [next] | [standalone]


#1820

FromAnthony Williams <anthony.ajw@gmail.com>
Date2011-02-01 13:51 +0000
Message-ID<87k4hjx3ph.fsf@justsoftwaresolutions.co.uk>
In reply to#1781
Alexander Terekhov <terekhov@web.de> writes:

> Anthony Williams wrote:
> [...]
>> You can of course make your atomic variables volatile too, and then they
>> DO become observable behaviour.
>
> Observable as in what? Memory mapped I/O variables and signal handlers
> aside, you can't mean debuggers and/or asm listings. The following
> programs

The C++ Standard defines "observable behaviour" to be the set of
accesses to volatile variables and I/O performed by the program.

The only requirement on a compiled program is that it produce the same
set of observable behaviour as that required by the abstract machine,
which includes accesses to volatile variables.

How you are supposed to observe the accesses to volatile variables is
not specified.

> int main() {
>   volatile int i;
>   // volatile write = has no observable effect
>   i = 1;
>   // volatile read = has no observable effect
>   int n = i;
>   // output: 1
>   std::cout << n;
> }
>
> int main() {
>   // output: 1
>   std::cout << 1;
> }
>
> can be translated into the same executable code.

FYI, gcc doesn't treat them the same, even with -O3: the first gets
translated to a store of 1 to a stack variable followed by a load from
that stack variable into a register, then a call to write that to
cout. The second just gets translated into a load of 1 into a register,
then a call to write that to cout. If you omit the "volatile" from the
first example then it is translated the same as the second.

Anthony
-- 
Author of C++ Concurrency in Action     http://www.stdthread.co.uk/book/
just::thread C++0x thread library             http://www.stdthread.co.uk
Just Software Solutions Ltd       http://www.justsoftwaresolutions.co.uk
15 Carrallack Mews, St Just, Cornwall, TR19 7UL, UK. Company No. 5478976

[toc] | [prev] | [standalone]


Back to top | Article view | comp.programming.threads


csiph-web