Page 1 of 1

Volatile

Posted: Mon Sep 01, 2008 6:14 pm
by ChazZeromus
I'd like to know, what exactly is the compiler doing with you manipulate data that is "volative". I hear that when something is volatile, it doesn't have any optimizations of any sort. What exactly are these memory optimizations?

Re: Volatile

Posted: Mon Sep 01, 2008 6:24 pm
by Brendan
Hi,
ChazZeromus wrote:I'd like to know, what exactly is the compiler doing with you manipulate data that is "volative". I hear that when something is volatile, it doesn't have any optimizations of any sort. What exactly are these memory optimizations?
Volatile means the variable may be changed by something the compiler can't know about.

For an example, consider this code:

Code: Select all

     while(timerTicks < endTick);
Now, a smart compiler might optimize this and generate something like:

Code: Select all

    mov eax,[timerTicks]
    mov ebx,[endTick]
.loopStart:
    cmp eax,ebx
    jb .loopStart
An even better compiler might optimize it more, and generate:

Code: Select all

.loopStart:
    jmp .loopStart
If you tell the compiler that the "timerTicks" variable might be changed in ways the compiler can't know about (e.g. incremented by a timer IRQ) then the compiler won't cache the variable in a register, and you're much more likely to get something like:

Code: Select all

    mov ebx,[endTick]
.loopStart:
    cmp [timerTicks],ebx
    jb .loopStart
Hope that makes sense...


Cheers,

Brendan

Re: Volatile

Posted: Mon Sep 01, 2008 6:33 pm
by ChazZeromus
Tanks alot!(and soldiers!) I could have looked at the disassembly but I was too lazy. lol. Thanks for the quick answer.

Re: Volatile

Posted: Mon Sep 01, 2008 6:40 pm
by ChazZeromus
Wait a sec about this:

Code: Select all

mov eax,[timerTicks]
    mov ebx,[endTick]
.loopStart:
    cmp eax,ebx
    jb .loopStart
Dude, this isn't smart! This would get stuck in a loop forever! Eax, and Ebx wouln't change period!

Re: Volatile

Posted: Mon Sep 01, 2008 9:09 pm
by Brendan
Hi,
ChazZeromus wrote:Wait a sec about this:

Code: Select all

mov eax,[timerTicks]
    mov ebx,[endTick]
.loopStart:
    cmp eax,ebx
    jb .loopStart
Dude, this isn't smart! This would get stuck in a loop forever! Eax, and Ebx wouln't change period!
Sure, but it corresponds to the original source code exactly, because the original source code would also be an endless loop (if the "timerTicks" variable wasn't updated by something the compiler can't know about).

A minor note here - I called it "smart" because the compiler was smart enough to realize that nothing changed the value of "timerTicks" and that it could be read once outside the loop rather than read lots of times inside the loop (which sounds a little funny in this context but it is an important optimization for "less trivial" code).


Cheers,

Brendan

Re: Volatile

Posted: Tue Sep 02, 2008 7:55 pm
by ChazZeromus
If this is true why not just create an endless loop instead of having a the trouble of comparing?

Because those lines in context, are generally, ridiculous if read without the higher source.

Re: Volatile

Posted: Wed Sep 03, 2008 6:05 am
by bewing
Because they show a case that actually happens in the real world, when you accidentally leave out a few ++ operators, and then optimize your code. Sometimes the optimizer outsmarts you, and makes debugging very confusing. And, getting back to the point of the thread, that is the entire point of the 'volatile' keyword -- to prevent the optimizer from optimizing away memory accesses that are needed, when they seem superfluous at first glance (because you are testing the same memory address, repeatedly).

Re: Volatile

Posted: Wed Sep 03, 2008 4:49 pm
by ChazZeromus
yeah, but if the only thing your doing is checking two register within a loop, it's pointless, I mean, a compiler should know what could doesn't belong.

Re: Volatile

Posted: Wed Sep 03, 2008 10:40 pm
by bewing
Heh. Nope. That would be AI. The compilers just optimize until they can't optimize any more.

Re: Volatile

Posted: Thu Sep 04, 2008 10:57 am
by quok
I know this is a thread on what the volatile keyword actually does and how to use it, but wouldn't it be proper to also point out alternatives to using volatile at all? Primitives like memory barriers are great, and of course mutual exclusion locking works nicely too. The whole point of them is to ensure proper access to variables that may change outside your current control path. Wise use of primitives like this can eliminate the need for most uses of volatile, but not all.

For instance, changing

Code: Select all

while(timerTicks < endTick);
to

Code: Select all

while ( timerTicks < endTick )
   mbarrier();
wouldn't require timerTicks to be volatile. It does, however, have the side effect of slowing down the loop, so you're less likely to return from the loop at exactly endTick, but that's not guaranteed by either example.

Re: Volatile

Posted: Thu Sep 04, 2008 9:19 pm
by ChazZeromus
what? I was just complaining about how useless that loop is, and a spinlock would not use just those only instructions.

Re: Volatile

Posted: Sat Sep 06, 2008 5:01 am
by JamesM
ChazZeromus wrote:what? I was just complaining about how useless that loop is, and a spinlock would not use just those only instructions.
Hi,

There are many cases where a programmer writes code that, when taken at face value, would not produce the best object code. Programmers may do this because it makes the source code easier to read - as a very trivial example consider:

(assume that b is a stack local int* and c is a stack local int)

Code: Select all

register int a = *b;
for(int i = 0; i < someCondition; i++)
{
  c += a;
}
versus

Code: Select all

for(int i = 0; i < someCondition; i++)
{
  c += *b;
}
The programmer (in the second case) has decided to save one line (the "register int a = *b;" line) and opted for tidier looking code. However, with the code as it is, "b" will be dereferenced at every loop iteration - slow(er) and not what the programmer intended. An optimising compiler will spot this and move the dereference outside the loop.

For the optimiser to spot the difference between the above (valid) case and the case that you (or rather Brendan) mention is difficult. Spotting specific cases is easy, but predicting that a variable may be affected beyond the current scope is, quite frankly, not really possible. That really is your job as a programmer.

Just like the "restrict" and "const" qualifiers, the "volatile" qualifier is a hint to the compiler about the intended usage of the variable, allowing it to (or denying it from) performing various optimisations.

Always remember that in the sequence "Programmer -> compiler -> machine" the only intelligent step is the Programmer. The compiler and machine are both dumb, until we get AI, at least.

Cheers,

James

Re: Volatile

Posted: Mon Sep 08, 2008 9:43 pm
by ChazZeromus
Yes, an AI wouldn't be needed, just a smart compilation process. Though slower, but is useful in final build if ever used.

Re: Volatile

Posted: Tue Sep 09, 2008 3:47 am
by Combuster
You claim you don't need AI, and yet you claim the opposite that you do? :roll:

Re: Volatile

Posted: Tue Sep 09, 2008 3:53 am
by JamesM
Yes, an AI wouldn't be needed, just a smart compilation process.
As combuster said - you've just contradicted yourself.