Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > Clarification on the applicability of compile-time optimization to astruct variable which encompasses a mixture of fields declared as volatileand non-volatile individually

Reply
Thread Tools

Clarification on the applicability of compile-time optimization to astruct variable which encompasses a mixture of fields declared as volatileand non-volatile individually

 
 
Myth__Buster
Guest
Posts: n/a
 
      07-05-2012
#include <stdio.h>

struct InterruptData
{
int numberOfInterrupts;
volatile int timer;
int numberOfTimesInterruptsMasked;
} InterruptMonitor;


/*
* Interrupt handler code.
*/

int main(void)
{
InterruptMonitor = InterruptMonitor;

printf("\n LOG - InterruptMonitor.numberOfInterrupts : %d \n",
InterruptMonitor.numberOfInterrupts);

printf("\n LOG - InterruptMonitor.timer : %d \n",
InterruptMonitor.timer);

printf("\n LOG - InterruptMonitor.numberOfTimesInterruptsMasked : %d \n",
InterruptMonitor.numberOfTimesInterruptsMasked);

return 0;
}

-------------

InterruptMonitor = InterruptMonitor; - Should this be a candidate for compile-time optimization in spite of having a field qualified as volatile?

Cheers,
Raghavan Santhanam
 
Reply With Quote
 
 
 
 
Ben Bacarisse
Guest
Posts: n/a
 
      07-05-2012
Myth__Buster <(E-Mail Removed)> writes:

> #include <stdio.h>
>
> struct InterruptData
> {
> int numberOfInterrupts;
> volatile int timer;
> int numberOfTimesInterruptsMasked;
> } InterruptMonitor;
>
>
> /*
> * Interrupt handler code.
> */
>
> int main(void)
> {
> InterruptMonitor = InterruptMonitor;

<snip>
> return 0;
> }
>
> -------------
>
> InterruptMonitor = InterruptMonitor; - Should this be a candidate for
> compile-time optimization in spite of having a field qualified as
> volatile?


I fear that your example may be one "a bit like" the code you really
care about, but I have to talk about what you post...

To a very large extent, the C standard washes it hands of volatile
objects. Sure, it says a fair bit about what *may* happen but it also
says "[w]hat constitutes an access to an object that has volatile-
qualified type is implementation-defined" (6.7.3 p7) and "[a]n actual
implementation need not evaluate part of an expression if it can deduce
that [...] no needed side effects are produced (including any caused by
[...] accessing a volatile object)" (5.1.2.3 p4).

Together, these give an implementation so much leeway that you often
need to refer to the implementation, not the standard. For example, an
implementation may well be able to deduce that the assignment is not a
"needed side effect", coming as it does at the start of main. Equally,
an implementation may treat all accesses to volatile-qualified objects
with kid gloves.

--
Ben.
 
Reply With Quote
 
 
 
 
Uncle Steve
Guest
Posts: n/a
 
      07-06-2012
On Thu, Jul 05, 2012 at 11:22:49PM +0100, Ben Bacarisse wrote:
> Myth__Buster <(E-Mail Removed)> writes:
>
> > #include <stdio.h>
> >
> > struct InterruptData
> > {
> > int numberOfInterrupts;
> > volatile int timer;
> > int numberOfTimesInterruptsMasked;
> > } InterruptMonitor;
> >
> >
> > /*
> > * Interrupt handler code.
> > */
> >
> > int main(void)
> > {
> > InterruptMonitor = InterruptMonitor;

> <snip>
> > return 0;
> > }
> >
> > -------------
> >
> > InterruptMonitor = InterruptMonitor; - Should this be a candidate for
> > compile-time optimization in spite of having a field qualified as
> > volatile?

>
> I fear that your example may be one "a bit like" the code you really
> care about, but I have to talk about what you post...
>
> To a very large extent, the C standard washes it hands of volatile
> objects. Sure, it says a fair bit about what *may* happen but it also
> says "[w]hat constitutes an access to an object that has volatile-
> qualified type is implementation-defined" (6.7.3 p7) and "[a]n actual
> implementation need not evaluate part of an expression if it can deduce
> that [...] no needed side effects are produced (including any caused by
> [...] accessing a volatile object)" (5.1.2.3 p4).
>
> Together, these give an implementation so much leeway that you often
> need to refer to the implementation, not the standard. For example, an
> implementation may well be able to deduce that the assignment is not a
> "needed side effect", coming as it does at the start of main. Equally,
> an implementation may treat all accesses to volatile-qualified objects
> with kid gloves.


This is a concern in my mind right now as I'm writing some posix
threads code, and so obviously there are a large number of variables
which ought to be declared volatile. I don't have a copy of the
standard, so I was wondering whether the volatile attribute is
inherited by structures contained within a structure declared
volatile. Example:


struct substruct {
int a, b;
};

struct container {
int n_coord;
struct substruct coord[];
};


volatile struct container c;

The question is, does c.coord[i].a have the volatile attribute?



Regards,

Uncle Steve

--
The moon has never been closer.

 
Reply With Quote
 
Uncle Steve
Guest
Posts: n/a
 
      07-06-2012
On Sat, Jul 07, 2012 at 09:20:57AM +1200, Ian Collins wrote:
> On 07/ 7/12 05:08 AM, Uncle Steve wrote:
> >On Thu, Jul 05, 2012 at 11:22:49PM +0100, Ben Bacarisse wrote:
> >>
> >>To a very large extent, the C standard washes it hands of volatile
> >>objects. Sure, it says a fair bit about what *may* happen but it also
> >>says "[w]hat constitutes an access to an object that has volatile-
> >>qualified type is implementation-defined" (6.7.3 p7) and "[a]n actual
> >>implementation need not evaluate part of an expression if it can deduce
> >>that [...] no needed side effects are produced (including any caused by
> >>[...] accessing a volatile object)" (5.1.2.3 p4).
> >>
> >>Together, these give an implementation so much leeway that you often
> >>need to refer to the implementation, not the standard. For example, an
> >>implementation may well be able to deduce that the assignment is not a
> >>"needed side effect", coming as it does at the start of main. Equally,
> >>an implementation may treat all accesses to volatile-qualified objects
> >>with kid gloves.

> >
> >This is a concern in my mind right now as I'm writing some posix
> >threads code, and so obviously there are a large number of variables
> >which ought to be declared volatile.

>
> What leads you to that conclusion? That line of though usually implies
> you are misunderstanding the relationship between volatile and threads.
>
> What are you trying to achieve with volatile?


Well, I have some data structures that will be accessed from arbitrary
threads, so I want to make sure there's no funny business happening
behind the scenes where the compiler decides that certain accesses are
optional.

Here's a little snippet of code which shows the issue, albeit without
nested structures:


#include <local_time.h>


struct sample_s {
T64 a, b;
};

typedef struct sample_s sample;

#define SAMPLES 100



#define nsclock(p) { \
volatile struct timespec T; \
clock_gettime(CLOCK_MONOTONIC, &T); \
p = T.tv_sec * 1000000000 + T.tv_nsec; \
}

void do_timing(sample * p)
{
volatile T64 s, e, v;
// volatile unsigned int i;

nsclock(s);
nsclock(s);

// for(i = 0; i < 1 ; i++);
nsclock(e);

p->a = (e - s);

nsclock(e);

p->b = (e - s);

return;
}


void emit_sample(sample *p)
{
fprintf(stdout, "%-5d %-5d %-5d\n", p->a, p->b, p->b - p->a);

return;
}




int main(char *argv, int argc)
{
sample tr[SAMPLES + 1];
int i;

tr[SAMPLES].a = tr[SAMPLES].b = 0;


for(i = 0; i < SAMPLES; i++)
do_timing(&tr[i]);

fprintf(stdout, "Timing results for %d samples:\n\n", SAMPLES);

fprintf(stdout, "%-5s %-5s %-5s\n", "A", "B", "B - A");

for(i = 0; i < SAMPLES; i++)
emit_sample(&tr[i]);

exit(0);
}


So, without including all the crap in local_time.h, I have to explain
a few definitions.

T64 is an unsigned long long int representing microseconds since
epoch, but I ended up using it as if it represented nanoseconds since
epoch since my i3 dual core laptop has a nanosecond-resolution timer.

The variable declared volatile are required otherwise some variable
accesses are optimized out, giving inaccurate results during the data
acquisition phase. The problems here are magnified when these access
patterns occur with competing threads. IIRC, mutexes are not memory
access barriers and solve different problems.


Regards,

Uncle Steve

--
The moon has never been closer.

 
Reply With Quote
 
Uncle Steve
Guest
Posts: n/a
 
      07-06-2012
On Fri, Jul 06, 2012 at 06:11:28PM -0400, Eric Sosman wrote:
> On 7/6/2012 2:01 PM, Uncle Steve wrote:
> >On Sat, Jul 07, 2012 at 09:20:57AM +1200, Ian Collins wrote:
> >>On 07/ 7/12 05:08 AM, Uncle Steve wrote:
> >>>[...]
> >>>This is a concern in my mind right now as I'm writing some posix
> >>>threads code, and so obviously there are a large number of variables
> >>>which ought to be declared volatile.
> >>
> >>What leads you to that conclusion? That line of though usually implies
> >>you are misunderstanding the relationship between volatile and threads.
> >>
> >>What are you trying to achieve with volatile?

> >
> >Well, I have some data structures that will be accessed from arbitrary
> >threads, so I want to make sure there's no funny business happening
> >behind the scenes where the compiler decides that certain accesses are
> >optional.

>
> Although the latest "C11" Standard adds some multi-threading
> support, I'll ignore that because (1) C11 implementations are not
> exactly thick upon the ground as yet, (2) you mentioned you're
> using Pthreads anyhow, and (3) I haven't studied the C11 threading
> stuff closely enough to be a competent commentator.
>
> So: As long as you're using an established non-C-specific
> threading framework, I suggest you visit comp.programming.threads,
> a newsgroup devoted to multi-threading issues. There you will learn
> that `volatile' is neither necessary *nor* sufficient in connection
> with variables shared between threads. (You needn't take my word on
> this: Just browse the comp.programming.threads archives and you'll
> see the local experts refuting this misunderstanding every couple
> weeks. It's comp.programming.threads' equivalent of `void main'.)
>
> Or, as my first threading teacher put it, "Don't Do That."


Is there are C standard threading framework?

Threaded code is a de-facto reality in today's multi-core environment.
Save for the embedded sector, most systems will run threads in
parallel, and that is that. C has to recognize this watershed moment
in the refinement of the language.

While the specifics of an implementation within a given operating
system are not C issues, certain common optimizations can be a problem
with certain algorithms, and so there ought to be a C solution to the
problem. What is it about the volatile attribute that makes it
insufficient in your mind to the problem presented by threaded code?


Regards,

Uncle Steve

--
The moon has never been closer.

 
Reply With Quote
 
Uncle Steve
Guest
Posts: n/a
 
      07-06-2012
On Sat, Jul 07, 2012 at 11:29:02AM +1200, Ian Collins wrote:
> On 07/ 7/12 06:33 AM, Uncle Steve wrote:
> >On Fri, Jul 06, 2012 at 06:11:28PM -0400, Eric Sosman wrote:
> >>On 7/6/2012 2:01 PM, Uncle Steve wrote:
> >>>On Sat, Jul 07, 2012 at 09:20:57AM +1200, Ian Collins wrote:
> >>>>On 07/ 7/12 05:08 AM, Uncle Steve wrote:
> >>>>>[...]
> >>>>>This is a concern in my mind right now as I'm writing some posix
> >>>>>threads code, and so obviously there are a large number of variables
> >>>>>which ought to be declared volatile.
> >>>>o
> >>>>What leads you to that conclusion? That line of though usually implies
> >>>>you are misunderstanding the relationship between volatile and threads.
> >>>>
> >>>>What are you trying to achieve with volatile?
> >>>
> >>>Well, I have some data structures that will be accessed from arbitrary
> >>>threads, so I want to make sure there's no funny business happening
> >>>behind the scenes where the compiler decides that certain accesses are
> >>>optional.
> >>
> >> Although the latest "C11" Standard adds some multi-threading
> >>support, I'll ignore that because (1) C11 implementations are not
> >>exactly thick upon the ground as yet, (2) you mentioned you're
> >>using Pthreads anyhow, and (3) I haven't studied the C11 threading
> >>stuff closely enough to be a competent commentator.
> >>
> >> So: As long as you're using an established non-C-specific
> >>threading framework, I suggest you visit comp.programming.threads,
> >>a newsgroup devoted to multi-threading issues. There you will learn
> >>that `volatile' is neither necessary *nor* sufficient in connection
> >>with variables shared between threads. (You needn't take my word on
> >>this: Just browse the comp.programming.threads archives and you'll
> >>see the local experts refuting this misunderstanding every couple
> >>weeks. It's comp.programming.threads' equivalent of `void main'.)
> >>
> >> Or, as my first threading teacher put it, "Don't Do That."

> >
> >Is there are C standard threading framework?

>
> Yes, read C11. If you are familiar with pthreads, you'll see where most
> of the new primitives originate.


Well, I don't follow gcc development, so I don't know when those
features will be available on my system.

> >Threaded code is a de-facto reality in today's multi-core environment.
> >Save for the embedded sector, most systems will run threads in
> >parallel, and that is that.

>
> Only if you incorporate threads in your code either explicitly or
> implicitly with something like OpenMP.


Well, sure, but I'd like to think that multithreaded applications will
be popular. It helps to improve the interactivity of applications
with a GUI frontend for one thing, never mind what you can do with
message-passing interfaces or asynchronus network I/O threads.

> >C has to recognize this watershed moment
> >in the refinement of the language.

>
> It has.


O.K., so do nested structure elements inherit the parent structure's
volatile attribute?

> >While the specifics of an implementation within a given operating
> >system are not C issues, certain common optimizations can be a problem
> >with certain algorithms, and so there ought to be a C solution to the
> >problem. What is it about the volatile attribute that makes it
> >insufficient in your mind to the problem presented by threaded code?

>
> Given you are the one going against conventional wisdom, what in your
> mind makes volatile a solution to the problem presented by threaded code?
>
> In addition, what is "the problem presented by threaded code"?


Well, code optimization from global CSE might eliminate memory
accesses to variable that could be modified by other threads in ways
that affect the algorithm. Depends of the code.


Regards,

Uncle Steve

--
The moon has never been closer.

 
Reply With Quote
 
Uncle Steve
Guest
Posts: n/a
 
      07-06-2012
On Fri, Jul 06, 2012 at 04:58:09PM -0700, Joshua Maurice wrote:
> On Jul 6, 11:01*am, Uncle Steve <(E-Mail Removed)> wrote:
> > On Sat, Jul 07, 2012 at 09:20:57AM +1200, Ian Collins wrote:
> > > On 07/ 7/12 05:08 AM, Uncle Steve wrote:
> > > >This is a concern in my mind right now as I'm writing some posix
> > > >threads code, and so obviously there are a large number of variables
> > > >which ought to be declared volatile.

> >
> > > What leads you to that conclusion? *That line of though usually implies
> > > you are misunderstanding the relationship between volatile and threads.

> >
> > > What are you trying to achieve with volatile?

> >
> > Well, I have some data structures that will be accessed from arbitrary
> > threads, so I want to make sure there's no funny business happening
> > behind the scenes where the compiler decides that certain accesses are
> > optional.
> >
> > [snip]
> >
> > The variable declared volatile are required otherwise some variable
> > accesses are optimized out, giving inaccurate results during the data
> > acquisition phase. *The problems here are magnified when these access
> > patterns occur with competing threads. *IIRC, mutexes are not memory
> > access barriers and solve different problems.

>
> To be topical, here's the answer for C11: volatile is useless as a
> portable threading construct. Do not use it. It's (maybe) useful in a
> portable way only for 3 obscure situations: MMIO, setjmp and longjmp
> stuff, and signal handling. If you properly use C11 mutexes, there is
> absolutely no need for volatile. To paraphrase you else-thread, there
> will be no "funny business" if you use mutexes correctly. It tells the
> compiler, the hardware, and anything else relevant, to obey the
> semantics of the mutex. volatile is similarly useless when you
> correctly use the new "weak" C11 atomics. volatile adds nothing
> (portably).
>
> Now, to finally answer your question, C11 threading semantics,
> including the lack of useful volatile semantics, is basically copied
> wholesale from pthreads. Don't use volatile as a portable threading
> construct with pthreads either. pthread mutexes do everything you
> need. volatile adds absolutely nothing (portably).
>
> (Yes, you can accomplish useful code with volatile for specific
> platform and specific compilers with specific settings. That's an
> "advanced" topic that I won't cover now.)
>
> Now, what do you mean by "mutexes are not memory access barriers"?
> Mutexes do two things: they provide blocking semantics for mutual
> exclusion, and they guarantee visibility ala the usual "happens-
> before" semantics. Mutexes are implemented with hardware memory
> fences / barriers. This is all true for mutexes in pthreads, win32
> threads, Boost threads, ACE threads, C11 threads, C++11 threads, and
> every case I can recall seeing the word "mutex".


Well, mutexes are barriers for the memory accesses associated with the
mutex itself, but not in general. Reading the above I can tell that
you think I'm using POSIX mutexes, however that is not the case. I am
using a custom locking scheme that allows for concurrent readers, but
is exclusive for writers. As a consequence, the behavior of
variables marked volatile in my code is critical, so I don't want to
mistakenly use it in a way that results in surprises.

Now you can say that what I am doing is non-portable, but you would
be wrong there since my algorithms are in fact portable as long as I
am following the rules of the C standard. Perhaps the proper term is
limited portability as I rely on a tiny amount of platform specific
asm. (One instruction.)


Regards,

Uncle Steve

--
The moon has never been closer.

 
Reply With Quote
 
Ian Collins
Guest
Posts: n/a
 
      07-06-2012
On 07/ 7/12 05:08 AM, Uncle Steve wrote:
> On Thu, Jul 05, 2012 at 11:22:49PM +0100, Ben Bacarisse wrote:
>>
>> To a very large extent, the C standard washes it hands of volatile
>> objects. Sure, it says a fair bit about what *may* happen but it also
>> says "[w]hat constitutes an access to an object that has volatile-
>> qualified type is implementation-defined" (6.7.3 p7) and "[a]n actual
>> implementation need not evaluate part of an expression if it can deduce
>> that [...] no needed side effects are produced (including any caused by
>> [...] accessing a volatile object)" (5.1.2.3 p4).
>>
>> Together, these give an implementation so much leeway that you often
>> need to refer to the implementation, not the standard. For example, an
>> implementation may well be able to deduce that the assignment is not a
>> "needed side effect", coming as it does at the start of main. Equally,
>> an implementation may treat all accesses to volatile-qualified objects
>> with kid gloves.

>
> This is a concern in my mind right now as I'm writing some posix
> threads code, and so obviously there are a large number of variables
> which ought to be declared volatile.


What leads you to that conclusion? That line of though usually implies
you are misunderstanding the relationship between volatile and threads.

What are you trying to achieve with volatile?

--
Ian Collins
 
Reply With Quote
 
Uncle Steve
Guest
Posts: n/a
 
      07-06-2012
On Sat, Jul 07, 2012 at 12:37:59PM +1200, Ian Collins wrote:
> On 07/ 7/12 08:27 AM, Uncle Steve wrote:
> >On Sat, Jul 07, 2012 at 11:29:02AM +1200, Ian Collins wrote:
> >>On 07/ 7/12 06:33 AM, Uncle Steve wrote:
> >>>
> >>>Is there are C standard threading framework?
> >>
> >>Yes, read C11. If you are familiar with pthreads, you'll see where most
> >>of the new primitives originate.

> >
> >Well, I don't follow gcc development, so I don't know when those
> >features will be available on my system.

>
> Then use your platform's native threading primitives.


Doing so would incur a performance penalty in comparison to my
synchronization primitives in some circumstances.

> >>>Threaded code is a de-facto reality in today's multi-core environment.
> >>>Save for the embedded sector, most systems will run threads in
> >>>parallelo, and that is that.
> >>
> >>Only if you incorporate threads in your code either explicitly or
> >>implicitly with something like OpenMP.

> >
> >Well, sure, but I'd like to think that multithreaded applications will
> >be popular. It helps to improve the interactivity of applications
> >with a GUI frontend for one thing, never mind what you can do with
> >message-passing interfaces or asynchronus network I/O threads.

>
> There already are.


Yes. There are many examples of such code.

> >>>C has to recognize this watershed moment
> >>>in the refinement of the language.
> >>
> >>It has.

> >
> >O.K., so do nested structure elements inherit the parent structure's
> >volatile attribute?

>
> A volatile T is a volatile T no matter what it contains.


Look. In threaded applications, the truth associated with the value
associated with certain variables can be somewhat indeterminate. If
that's true in your code, you might want to be aware of it.

> >>>While the specifics of an implementation within a given operating
> >>>system are not C issues, certain common optimizations can be a problem
> >>>with certain algorithms, and so there ought to be a C solution to the
> >>>problem. What is it about the volatile attribute that makes it
> >>>insufficient in your mind to the problem presented by threaded code?
> >>
> >>Given you are the one going against conventional wisdom, what in your
> >>mind makes volatile a solution to the problem presented by threaded code?
> >>
> >>In addition, what is "the problem presented by threaded code"?

> >
> >Well, code optimization from global CSE might eliminate memory
> >accesses to variable that could be modified by other threads in ways
> >that affect the algorithm. Depends of the code.

>
> If the code depends on volatile, it is broken. Use the atomics or
> synchronisation primitives provided by the language or platform. They
> exist for a reason.


You aren't listening to me.



Regards,

Uncle Steve

--
The moon has never been closer.

 
Reply With Quote
 
Eric Sosman
Guest
Posts: n/a
 
      07-06-2012
On 7/6/2012 2:01 PM, Uncle Steve wrote:
> On Sat, Jul 07, 2012 at 09:20:57AM +1200, Ian Collins wrote:
>> On 07/ 7/12 05:08 AM, Uncle Steve wrote:
>>>[...]
>>> This is a concern in my mind right now as I'm writing some posix
>>> threads code, and so obviously there are a large number of variables
>>> which ought to be declared volatile.

>>
>> What leads you to that conclusion? That line of though usually implies
>> you are misunderstanding the relationship between volatile and threads.
>>
>> What are you trying to achieve with volatile?

>
> Well, I have some data structures that will be accessed from arbitrary
> threads, so I want to make sure there's no funny business happening
> behind the scenes where the compiler decides that certain accesses are
> optional.


Although the latest "C11" Standard adds some multi-threading
support, I'll ignore that because (1) C11 implementations are not
exactly thick upon the ground as yet, (2) you mentioned you're
using Pthreads anyhow, and (3) I haven't studied the C11 threading
stuff closely enough to be a competent commentator.

So: As long as you're using an established non-C-specific
threading framework, I suggest you visit comp.programming.threads,
a newsgroup devoted to multi-threading issues. There you will learn
that `volatile' is neither necessary *nor* sufficient in connection
with variables shared between threads. (You needn't take my word on
this: Just browse the comp.programming.threads archives and you'll
see the local experts refuting this misunderstanding every couple
weeks. It's comp.programming.threads' equivalent of `void main'.)

Or, as my first threading teacher put it, "Don't Do That."

--
Eric Sosman
http://www.velocityreviews.com/forums/(E-Mail Removed)d


 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
"Try:" which only encompasses head of compound statement Jameson.Quinn@gmail.com Python 9 08-29-2007 12:58 AM
sizeof(aStruct) returns fault number nass C++ 2 09-22-2006 03:24 PM
Applicability KB 831138: app that uses WebRequest has OutOfMemoryE =?Utf-8?B?dmVjb3pvQG9ubGluZS5ub3NwYW0=?= ASP .Net 9 01-05-2006 08:50 PM
wired / wireless network mixture or not ? ReceT Wireless Networking 3 07-12-2004 02:54 AM
gaussian mixture? GBartgo C++ 2 11-02-2003 12:10 AM



Advertisments