Thread: VOLATILE vs Normal VARIABLE N C

  1. #16
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,981
    >> Yes it does. That's the whole point. If memory changes due to a device, volatile is what ensures that change is seen.
    When I say "memory visibility", I'm not talking about compiler optimizations. Volatile only affects compiler behavior - it does not affect anything at the hardware level.
    Memory barrier - Wikipedia, the free encyclopedia

    gg

  2. #17
    Registered User
    Join Date
    Apr 2006
    Posts
    2,149
    In modern CPUs, You don't always need memory barriers when sharing data between threads or processes. It depends on how the data is used. You do need the basic guarantee that a thread's view of memory does not revert from to an earlier state; so you don't un-see a state, but this is guaranteed by the same hardware that ensure that memory writes from the one thread don't revert. And you need proper cache invalidation rules. But as it happens, cache invalidation rules generally don't need special instructions.

    Also, the fact that volatile prevents a particular optimization that the compiler is responsible for is besides the point. The language standard does not differentiate between the compiler and the hardware, they're both part of the implementation.
    It is too clear and so it is hard to see.
    A dunce once searched for fire with a lighted lantern.
    Had he known what fire was,
    He could have cooked his rice much sooner.

  3. #18
    Master Apprentice phantomotap's Avatar
    Join Date
    Jan 2008
    Posts
    5,108
    [Edit]TL;DR: a `volatile' variable simply doesn't pay for itself when it comes to concurrency issues.[/Edit]

    O_o

    You seem to be confused with regards to what Codeplug has said.

    If you are using your concurrency primitives carefully and correctly you are protected against undesirable effects of concurrency by definition.

    If you aren't using concurrency primitives without care or incorrectly `volatile' will almost never save you.

    An example would be like what you might write for a partial (read only) barrier with multiple phases against `volatile' on "x86" architecture. (The example would see a `volatile' variable potentially cached, at least theoretically, during one phase and read again at a later phase where both phases use the same partial protection mechanism.)

    The problem is, reality trumps the thought process involved in using `volatile' as a kind of "concurrency support". In my test, a lot of them, only three cases of such usage resulted in correct code. (I analyzed the assembler produced. I did not run the code. Yes, the examples were intentionally that simple.) To be clear here, there was not just three cases where it would have been useful for the assumption to work out. Furthermore, altering the code to use either more elaborate primitives, isolating the relevant bits behind atomic operations, or changing the implementation to a pattern with a single phase resulted in correct code for all cases regardless whether or not `volatile' was used.

    Here then then the assumption that `volatile' will do anything more, as in over what the concurrency primitives already guarantee, to prevent caching is not carefully considered use of concurrency primitives.

    The point here isn't even tangentially related to any standard. This is simply reality showing up to say that it is almost always wrong to reach for `volatile' for concurrent code.

    Because it depends on flaky factors, like arguments to the compiler, `volatile' just isn't worth buying for "concurrency support".

    With that in mind, the thought that `volatile' will "help" your compiler produce correct code in the face of things like caching only really serves to prevent perfectly valid optimization, such as those it might perform between acquiring and releasing a lock, without buying you anything because you may very well find it necessary to restructure or use more expensive primitives in any event.

    Soma

  4. #19
    Registered User
    Join Date
    Mar 2011
    Posts
    546
    tl;dr;
    'volatile' tells the compiler what to do. it doesn't tell the processor.
    modern processors can reorder memory reads and writes at the hardware level, regardless of the order of instructions in the assembly code.
    http://en.wikipedia.org/wiki/Memory_...rative_example

  5. #20
    Registered User
    Join Date
    Apr 2006
    Posts
    2,149
    Yes instruction reordering happens. It happens when volatile is not used, it happens when volatile is used, and it happens when relaxed atomic access is used.

    My point is that a volatile read is functionally identical to a relaxed atomic load, and both are different from a normal variable read.
    It is too clear and so it is hard to see.
    A dunce once searched for fire with a lighted lantern.
    Had he known what fire was,
    He could have cooked his rice much sooner.

  6. #21
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,981
    >> functionally identical to a relaxed atomic load
    volatile doesn't provide atomicity - you're at the mercy of your compiler and hardware there.

    gg

  7. #22
    Registered User
    Join Date
    Apr 2006
    Posts
    2,149
    True, but atomicity for primitive types is not hard to come by.
    It is too clear and so it is hard to see.
    A dunce once searched for fire with a lighted lantern.
    Had he known what fire was,
    He could have cooked his rice much sooner.

  8. #23
    TEIAM - problem solved
    Join Date
    Apr 2012
    Location
    Melbourne Australia
    Posts
    1,907
    When programming microcontrollers, "volatile" is very important.

    A problem when writing interrupts is that some variables are only modified by an interrupt routine, and then read in the program (such as a flag).

    The optimiser will look at the flag in the code and see that the (main) code doesn't change the flag from its initial value -> So the initial value is substituted and shortcuts are made

    i.e.
    Code:
    int flag=0;
    
    ...
    
    /* This section will be removed from the code */
    if (flag == 1)
    {
      /*do something*/
    }
    When programming, you need to indicate to the compiler that the value of the variable may change elsewhere; so don't do any optimisations with that variable. This is done by using the "volatile" keyword.

    This is such a common mistake when programming microcontrollers, that it appears at question 1 on the FAQ for the AVR Frequently Asked Questions

    It is also explained here in a PIC FAQ Frequently Asked Questions (FAQ) about C on the Microchip PIC - This example also brings up the issue of delays. You would not have an accurate delay using this technique, but if you were just looking for the program to stop for a second or two...
    Fact - Beethoven wrote his first symphony in C

  9. #24
    Registered User
    Join Date
    Apr 2006
    Posts
    2,149
    That's demonstrative, because hardware interrupts are effectively other processes. A micro-controller is not going to provide atomic primitives. Nor is it going to provide any way to guarantee atomicity for large types, as C11 would require of all memory accesses if the two threads of execution were synchronized (which they can't be, because of a lack of atomics). So volatile is the way to go.
    It is too clear and so it is hard to see.
    A dunce once searched for fire with a lighted lantern.
    Had he known what fire was,
    He could have cooked his rice much sooner.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Doubt regarding structure padding and normal variable
    By karthik537 in forum C Programming
    Replies: 6
    Last Post: 10-03-2012, 08:26 AM
  2. Volatile Variable.
    By nagavardna in forum C Programming
    Replies: 2
    Last Post: 04-19-2012, 03:34 AM
  3. Difference between global variable and volatile
    By karthik537 in forum C Programming
    Replies: 4
    Last Post: 02-29-2012, 11:28 AM
  4. Guaranteed read from volatile variable
    By cyberfish in forum C++ Programming
    Replies: 17
    Last Post: 08-15-2011, 09:00 AM
  5. Normal maps: Get normal x/y/z from color
    By Devils Child in forum Game Programming
    Replies: 2
    Last Post: 08-09-2009, 12:01 PM