Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.programming.threads > #1781 > unrolled thread
| Started by | Alexander Terekhov <terekhov@web.de> |
|---|---|
| First post | 2011-02-01 14:17 +0100 |
| Last post | 2011-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.
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
| From | Alexander Terekhov <terekhov@web.de> |
|---|---|
| Date | 2011-02-01 14:17 +0100 |
| Subject | Re: 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]
| From | Alexander Terekhov <terekhov@web.de> |
|---|---|
| Date | 2011-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]
| From | Dmitriy Vyukov <dvyukov@gmail.com> |
|---|---|
| Date | 2011-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]
| From | Alexander Terekhov <terekhov@web.de> |
|---|---|
| Date | 2011-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]
| From | Alexander Terekhov <terekhov@web.de> |
|---|---|
| Date | 2011-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]
| From | Alexander Terekhov <terekhov@web.de> |
|---|---|
| Date | 2011-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]
| From | Dmitriy Vyukov <dvyukov@gmail.com> |
|---|---|
| Date | 2011-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]
| From | Dmitriy Vyukov <dvyukov@gmail.com> |
|---|---|
| Date | 2011-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]
| From | Joshua Maurice <joshuamaurice@gmail.com> |
|---|---|
| Date | 2011-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]
| From | Anthony Williams <anthony.ajw@gmail.com> |
|---|---|
| Date | 2011-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