This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Problem with optimisation of volatiles

Hi there All,

I have a problem which seemed to be defying explanation, but I have come up with a theory. Could I possibly have some feedback on whether the following is likely, plausible, possible, untrue or downright rubbish?

If one reads the contents of a CAN or ADC chip register at a particular address, then the label volatile is placed upon that address to prevent the compiler optimising out repeat readings of the address. If one reads the contents of the address into a variable, then the compiler would automatically treat the contents of this variable with similar care.

Is it possible that there has been an oversight with statements where the contents of a variable depend on the contents of a volatile by way of an if statement, ie...

normal_var=volatile_var;

...is correctly optimised, but...

normal_var=voltile_var;
if (normal_var=0x00)
   {
   another_normal_var+=1;
   }

...is not correctly optimised all of the time, dependant on the surrounding code, unless normal_var itself is declared to be volatile?

For info - am using optimisation level...

OPTIMIZE(3,SPEED)

...and am using version...

C166 COMPILER V4.11

Any thoughts, or is any or all of the above thoughts and understanding way off the mark?


Yours (grateful for any input),


Richard.

Parents
  • My question is what will happen to the lines...

    	i *= 2;
            write_to_dac(i);

    ...because i isn't defined as volatile?

    Impossible to say. Whatever the compiler decides is best, but remains the meaning of the code, will happen.

    You suggest that it should be untouched by the optimiser.

    No. Nobody was suggesting that. It's the exact opposite: it may be manipulated by the optimizer, exactly because there's no volatile qualifier stopping it from doing that. But even so, the optimizer is not allowed to just break your code --- volatile qualifiers are needed only in those cases where the optimizer might break code because it doesn't know all there is to know about a variable. That's the case whenever a variable's value can change, but there's no line of C code in the main execution path responsible for it that the compiler would know about being responsible for that.

    You somehow seem to believe that there's no middle ground between constant and volatile. But there is. Lots of it, actually, and it's what all ordinary variables do behave like.

Reply
  • My question is what will happen to the lines...

    	i *= 2;
            write_to_dac(i);

    ...because i isn't defined as volatile?

    Impossible to say. Whatever the compiler decides is best, but remains the meaning of the code, will happen.

    You suggest that it should be untouched by the optimiser.

    No. Nobody was suggesting that. It's the exact opposite: it may be manipulated by the optimizer, exactly because there's no volatile qualifier stopping it from doing that. But even so, the optimizer is not allowed to just break your code --- volatile qualifiers are needed only in those cases where the optimizer might break code because it doesn't know all there is to know about a variable. That's the case whenever a variable's value can change, but there's no line of C code in the main execution path responsible for it that the compiler would know about being responsible for that.

    You somehow seem to believe that there's no middle ground between constant and volatile. But there is. Lots of it, actually, and it's what all ordinary variables do behave like.

Children
  • Hi Hans,


    You suggest that it should be untouched by the optimiser.

    No. Nobody was suggesting that.


    In Mike's message is says...


    You are suggesting that the compiler might optimize it...Well, it's not going to happen because ADC is volatile.


    ...which I took to mean that Mike was suggesting it would be untouched by the optimiser.


    You somehow seem to believe that there's no middle ground between constant and volatile... - ordinary variables.


    I am happy with the fact that variable may, well vary (for want of a better word). I am also happy with the opimiser optimising algorithms where all the numbers start off within the code.

    I am less happy (in the knowledge sense) or what happens to algorithms which manipulate variables that have been loaded with numbers from external sources such as ADC's and CAN chips.

    From what I can make out...

    1) We assign the volatile qualifier to anything coming from an external source.

    2) The compiler will not assume a variable is volatile unless you explicitly define it as such.

    ...so given this piece of code...

    extern int volatile ADC;
    int i;
    for (;;)
    {
        i = ADC;
        i *= 2;
        write_to_dac(i);
    }
    

    ...you would expect the part of the code...

    for (;;)
       {
       i = ADC;
       }
    

    ...to be protected from optimisation, but that the compiler would treat the lines containing non volatile variables...

    
    for (;;)
       {
       i *=2;
       write_to_DAC(i);
       }
    
    

    ...as though it could caculate the final result of i, and just write it to the DAC once, the value of i being whatever the compiler thinks the answer of 0^inf is.
    by the compiler in the case.

    I'm assuming that this is not the case, and am looking for some kind of formal statement of whatever rules 3 onwards are for how we should treat variables which interact with volatiles.

    Does that make my problem/confusion any clearer?


    Yours,


    Rich.

  • You've broken your original code into pieces in a way the optimizer is already forbidden to do it, regardless of any usages of the "volatile" keyword.

    The two parts of the code that really exist are:

    	i = ADC
    and
    	i += 2;
    	write_do_DAC(i)

    The loop around this all has nothing to do with the effect of volatile, because there's one volatile variable (ADC) being used inside the loop.

    The optimizer is already forbidden to remove the call to write_to_DAC() by the simple fact that it's a function call. No volatile needed to explain that.

    The optimizer is forbidden to assume it can pre-compute the value of i to be passed to write_to_DAC because it's computed using a non-local, non-constant-qualified variable: ADC. It doesn't matter at all that ADC is qualified volatile, for that.

    In short: I think you're worrying too much. You really only need "volatile" to tell the compiler "Beware! There's stuff going on with this variable that you don't understand."

  • In Mike's message is says...

    You are suggesting that the compiler might optimize it...Well, it's not going to happen because ADC is volatile.

    ...which I took to mean that Mike was suggesting it would be untouched by the optimiser.


    Wrong. Words taken out of context.
    I still suggest that you come up with a real-world example of C code and possibly undesirable optimizations by the compiler on that code. Then there would be a basis for discussion. If it's not possible to think of such an example, then the problem does not exist.

    Regards,
    - mike