Does this allocate memory?

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Alexander Terekhov

    #31
    Re: Does this allocate memory?


    Karl Heinz Buchegger wrote:[color=blue]
    >
    > Karl Heinz Buchegger wrote:[color=green]
    > >
    > > ???
    > > There seems to be a misconception of what volatile really does.
    > > In the above, volatile doesn't do, what you seem to think it does.[/color]
    >
    > Apologies.
    > It was my fault. A few seconds after hitting 'send', I realized what you
    > are aming at. And it will work. You are right and I was wrong.
    >
    > One more time: Apologies.[/color]

    Sorry, but volatile *indeed* doesn't do what you seem to think it
    does. Nobody knows what it does because it's totally brain-damaged
    "concept".

    So, you're wrong and I'm right, of course.

    regards,
    alexander.

    Comment

    • Jingz

      #32
      Re: Does this allocate memory?

      On Thu, 24 Jul 2003 10:35:40 -0400, Alexander Terekhov wrote:

      [color=blue]
      > Karl Heinz Buchegger wrote:
      > Apologies.
      > It was my fault. A few seconds after hitting 'send', I realized what
      > you are aming at. And it will work. You are right and I was wrong.
      >[/color]

      No problemo, wasn't going to say anything ;)
      [color=blue]
      >
      > Sorry, but volatile *indeed* doesn't do what you seem to think it does.
      > Nobody knows what it does because it's totally brain-damaged "concept".
      >
      > So, you're wrong and I'm right, of course.
      >
      > regards,
      > alexander.[/color]

      I've bever used it myself, and without looking it up in the ARM or google
      or anything, I seem to recall volitile being used to keep the compiler
      from optimizing out necessary code that looks harmless, a simple example
      might be a (poorly written) multithreaded program:

      void thread1()
      {
      int i;
      invokethread( thread2, &i );

      i = 1;

      sleep( 100 );

      while( i == 2 );

      ..
      ..
      ..


      }

      void *thread2( void *arg )
      {
      int *p = (int *)arg;

      *p = 2;

      return 0;
      }

      --------

      In this example, admittedly braindead, a clever compiler might look at
      thread1 and see that a locally-scoped 'i' could not be modified by
      'sleep', and the next check "while" will never succeed, and it might be
      optimized out. by declaring 'i' as volatile, the compiler must honor all
      references to its value.

      This actally has applications in interrupt-driven device drivers, as I
      say I've never had a need for it, and I could be wrong! Its been some
      years since I looked up its function.

      -Curt

      Comment

      • Peter van Merkerk

        #33
        Re: Does this allocate memory?

        "Jingz" <e@spam.com> wrote in message
        news:pan.2003.0 7.25.02.00.38.9 1210.28231@spam .com...[color=blue]
        > On Thu, 24 Jul 2003 10:35:40 -0400, Alexander Terekhov wrote:[color=green]
        > > Sorry, but volatile *indeed* doesn't do what you seem to think it[/color][/color]
        does.[color=blue][color=green]
        > > Nobody knows what it does because it's totally brain-damaged[/color][/color]
        "concept".[color=blue][color=green]
        > >
        > > So, you're wrong and I'm right, of course.
        > >
        > > regards,
        > > alexander.[/color]
        >
        > I've bever used it myself, and without looking it up in the ARM or[/color]
        google[color=blue]
        > or anything, I seem to recall volitile being used to keep the compiler
        > from optimizing out necessary code that looks harmless, a simple[/color]
        example[color=blue]
        > might be a (poorly written) multithreaded program:[/color]

        The C++ standard doesn't care about multi-threading. Making variables
        volatile will not guarantee correct behaviour in a multi-threaded
        environment. Unless you know exactly what your compiler does with the
        volatile specification and what that means for the execution
        environment, the volitile keyword is of little or no use in most cases.

        Non volatile variables may loaded at (more or less) arbitratrary times
        from memory into a processor register and written back to memory at
        (more or less) arbitrary times as well, in the meanwhile the value of
        the value may have been changed many times without those changes being
        reflected in memory. This optimization is problematic when multiple
        threads access the same variable, as they essentially may operate on
        their copy of the variable and don't see the changes made by the other
        threads. Usually declaring a variable volatile means that the value of a
        variable is loaded from memory every time it is needed, and written back
        to memory every time its value is changed. However this doesn't
        guarantee correct behaviour in a multi-threaded enviroment.

        Example:

        volatile int v=0;

        void ThreadA()
        {
        for(int i = 0; i < 1000; ++i)
        {
        ++v;
        }
        }

        void ThreadB()
        {
        for(int i = 0; i < 1000; ++i)
        {
        ++v;
        }
        }

        So the question is what will be the value of 'v' when threads A and B
        have completed? The answer is that the value of 'v' can be anything
        between 1000 and 2000. This is because the line ++v may very well be
        translated to three processor instructions:

        mov ecx, [v];// Load value from memory into ecx register.
        inc ecx // Increment value of ecx register
        mov [v], ecx // Write value back to memory.

        The problem is that a thread context switch can occure after every
        processor instruction. If thread A loads the value 0 from memory into
        ecx, and immediately after that instruction a context switch to thread B
        occures thread B will read a 0 value for v as well. Now lets suppose
        thread B can complete without a context switches to thread A. In that
        case the value of variable v in memory will be 1000 at that point in
        time. However when thread A continues it will still have 0 in its ecx
        register, and after the first iteration of the loop in thread A the
        value of v in memory will go back from 1000 to 1. Consequently when
        thread A finishes the value of 'v' will be 1000. This is just one
        example what may go wrong.

        Moral of this story; for proper thread synchronisation you will have to
        rely on the facilities offered by the platform, C++ cannot help you
        here.

        --
        Peter van Merkerk
        peter.van.merke rk(at)dse.nl



        Comment

        • Alexander Terekhov

          #34
          Re: Does this allocate memory?


          Jingz wrote:
          [...][color=blue]
          > I've bever used it myself, and without looking it up in the ARM or google
          > or anything, I seem to recall volitile being used to keep the compiler
          > from optimizing out necessary code that looks harmless, a simple example
          > might be a (poorly written) multithreaded program: ....[/color]

          Heck. Advice: *PLONK* volatiles.


          (Subject: Re: Volatile and threads.)


          (Subject: Re: Does anyone think 'volatile' is a platform-independent
          way to make variable access thread safe?)

          regards,
          alexander.

          Comment

          • Jingz

            #35
            Re: Does this allocate memory?

            > The C++ standard doesn't care about multi-threading. Making variables[color=blue]
            > volatile will not guarantee correct behaviour in a multi-threaded
            > environment. Unless you know exactly what your compiler does with the[/color]

            Reading some of the other posts here I can understand why you jumped to
            the conclusion that I don't know the difference between the language and
            the system upon which it runs, I think you missed the point of my example.

            More plainly, my point was that the 'volatile' qualifier prevents the
            compiler from removing references to code that appear to have no effect,
            specifically, I presented an example where the address of that variable
            was known to another thread of execution.

            Precicely because c++ has no concern for threads of execution, interrupt
            handlers, pre-emption or any other such higher-level concepts, it must be
            told- "no, I really mean check a variable multiple times even though no
            code appears to change it between checks, I know better"

            Your point about variables being loaded into registers at random times is
            well taken, a compiler can decide to sample the value once from main RAM,
            then stick it in a register and continue to test it there, I would presume
            the 'volatile' qualifier would also prevent this behavior.

            [color=blue]
            > Moral of this story; for proper thread synchronisation you will have to
            > rely on the facilities offered by the platform, C++ cannot help you
            > here.[/color]

            Absolutely, and thank you for pointing it out so clearly to anyone else
            following this thread who might have also mis-interpreted my example.

            -Curt

            Comment

            • Peter van Merkerk

              #36
              Re: Does this allocate memory?

              "Jingz" <e@spam.com> wrote in message
              news:pan.2003.0 7.25.22.22.03.3 59404.7962@spam .com...[color=blue][color=green]
              > > The C++ standard doesn't care about multi-threading. Making variables
              > > volatile will not guarantee correct behaviour in a multi-threaded
              > > environment. Unless you know exactly what your compiler does with the[/color]
              >
              > Reading some of the other posts here I can understand why you jumped to
              > the conclusion that I don't know the difference between the language and
              > the system upon which it runs, I think you missed the point of my example.[/color]

              Don't worry, I didn't make any assumptions about your knowledge, and I did
              see the point of you example (the point was clear enough even for me to see
              it).

              The reason I responded is that your posting seemed to confirm a popular
              misconception that 'volatile' qualifier would help to solve at least some
              multithreading issues. It does not, period. It only gives people a false
              sense of security. Misconceptions like this can lead to extremely difficult
              to track down bugs. Good luck finding a unreproducable bug that shows its
              ugly face about 10 times a year at totally arbitrary times!

              I have written plenty of multi-threaded code, but never had any use for the
              'volatile' keyword.
              The 'volatile' qualifier may have its uses in very particular cases, but
              that depends entirely on the platform and the compiler.
              [color=blue]
              > More plainly, my point was that the 'volatile' qualifier prevents the
              > compiler from removing references to code that appear to have no effect,
              > specifically, I presented an example where the address of that variable
              > was known to another thread of execution.
              >
              > Precicely because c++ has no concern for threads of execution, interrupt
              > handlers, pre-emption or any other such higher-level concepts, it must be
              > told- "no, I really mean check a variable multiple times even though no
              > code appears to change it between checks, I know better"
              >
              > Your point about variables being loaded into registers at random times is
              > well taken, a compiler can decide to sample the value once from main RAM,
              > then stick it in a register and continue to test it there, I would presume
              > the 'volatile' qualifier would also prevent this behavior.[/color]

              Yes, it does force the compiler to access memory for that variable whenever
              it is used or changed. But that still doesn't guarantee correct behaviour in
              a multi-threaded environment. Note that the example I provided used a
              volatile variable to communicate between two threads, and even in that case
              it is not guaranteed it produces the correct result. Many processors cannot
              directly manipulate values in memory and have to use registers to do the
              actual arithmetic. So even manipulating volatile variables will typically
              require several instructions to load, modify and store the variable value.
              Consequently modifying a volatile variable cannot be considered to be atomic
              operation, hence the 'volatile' qualifier does not guarantee correct
              behaviour in a multi-threaded environment.

              The funny thing with my example is that if it is compiled with an optimizing
              compiler but without the 'volatile' qualifier for variable 'v', the chance
              of getting the expected result might actually be higher. If 'v' isn't
              volatile the compiler may replace the for loop with 'v+=1000;', which is
              much less likely to be interrupted by a context switch.

              --
              Peter van Merkerk
              peter.van.merke rk(at)dse.nl


              Comment

              • Alexander Terekhov

                #37
                Re: Does this allocate memory?


                Peter van Merkerk wrote:
                [...][color=blue]
                > The funny thing with my example is that if it is compiled with an optimizing
                > compiler but without the 'volatile' qualifier for variable 'v', the chance
                > of getting the expected result might actually be higher. If 'v' isn't
                > volatile the compiler may replace the for loop with 'v+=1000;', which is
                > much less likely to be interrupted by a context switch.[/color]

                Compiler *may* replace the for loop with 'v+=1000;' even if v is
                volatile. You still don't get it, I'm afraid.

                regards,
                alexander.

                Comment

                • Alexander Terekhov

                  #38
                  Re: Does this allocate memory?


                  Peter van Merkerk wrote:
                  [...][color=blue]
                  > Though it doesn't prove anything, on all compilers I ever tried, the
                  > volatile keyword does actually affect the generated code, but not in a way
                  > it is of any use in a multi-threaded environment. If you are right, I wonder
                  > why compilers bother doing something with the 'volatile' keyword instead of
                  > treating it the same way they typically do with the 'register' keyword, i.e.
                  > ignore it.[/color]

                  Well, in this case, the reason is nothing but "stupidity rules", I
                  think. As I said, volatile is totally brain-damaged.




                  regards,
                  alexander.

                  Comment

                  Working...