Memory Consistency Errors

Discussion in 'Java' started by mei, Feb 13, 2007.

  1. mei

    mei Guest

    Hi,
    While reading the tutorial
    http://java.sun.com/docs/books/tutorial/essential/concurrency/index.html,
    something caught my attention:
    It is said that memory consistency errors can occur even when atomicity
    of reading/writing access is guaranteed with volatile.
    However they don't develop this matter.
    Is there somebody that could explain me more how could this happen?
    Thank in advance.
    mei, Feb 13, 2007
    #1
    1. Advertising

  2. mei

    Eric Sosman Guest

    mei wrote On 02/13/07 14:26,:
    > Hi,
    > While reading the tutorial
    > http://java.sun.com/docs/books/tutorial/essential/concurrency/index.html,
    > something caught my attention:
    > It is said that memory consistency errors can occur even when atomicity
    > of reading/writing access is guaranteed with volatile.
    > However they don't develop this matter.
    > Is there somebody that could explain me more how could this happen?
    > Thank in advance.


    Accesses to main memory might not occur in the same
    order that the CPU initiated them, particularly for writes
    (which often go through hardware write buffers so the CPU
    needn't wait for them). If CPU 1 writes the Answer to
    location A and then writes the AnswerIsReady flag to B,
    CPU 2 may see the change to B before it sees the change
    to A, and thus get the WrongAnswer. Making either or both
    writes atomic doesn't help; what's needed is something
    called a "memory barrier."

    --
    Eric Sosman, Feb 13, 2007
    #2
    1. Advertising

  3. mei wrote:
    > Hi,
    > While reading the tutorial
    > http://java.sun.com/docs/books/tutorial/essential/concurrency/index.html,
    > something caught my attention:
    > It is said that memory consistency errors can occur even when atomicity
    > of reading/writing access is guaranteed with volatile.
    > However they don't develop this matter.
    > Is there somebody that could explain me more how could this happen?
    > Thank in advance.


    I looked and couldn't find the reference you mentioned. Do you have the
    URL of the page you saw that on?

    Thanks,

    --

    Knute Johnson
    email s/nospam/knute/
    Knute Johnson, Feb 14, 2007
    #3
  4. Eric Sosman wrote:
    > mei wrote On 02/13/07 14:26,:
    >> Hi,
    >> While reading the tutorial
    >> http://java.sun.com/docs/books/tutorial/essential/concurrency/index.html,
    >> something caught my attention:
    >> It is said that memory consistency errors can occur even when atomicity
    >> of reading/writing access is guaranteed with volatile.
    >> However they don't develop this matter.
    >> Is there somebody that could explain me more how could this happen?
    >> Thank in advance.

    >
    > Accesses to main memory might not occur in the same
    > order that the CPU initiated them, particularly for writes
    > (which often go through hardware write buffers so the CPU
    > needn't wait for them). If CPU 1 writes the Answer to
    > location A and then writes the AnswerIsReady flag to B,
    > CPU 2 may see the change to B before it sees the change
    > to A, and thus get the WrongAnswer. Making either or both
    > writes atomic doesn't help; what's needed is something
    > called a "memory barrier."
    >


    Is that not what you get with volatile?

    --

    Knute Johnson
    email s/nospam/knute/
    Knute Johnson, Feb 14, 2007
    #4
  5. mei

    Lew Guest

    mei wrote:
    >> Hi,
    >> While reading the tutorial
    >> http://java.sun.com/docs/books/tutorial/essential/concurrency/index.html,
    >> something caught my attention:
    >> It is said that memory consistency errors can occur even when
    >> atomicity of reading/writing access is guaranteed with volatile.
    >> However they don't develop this matter.
    >> Is there somebody that could explain me more how could this happen?
    >> Thank in advance.


    Knute Johnson wrote:
    > I looked and couldn't find the reference you mentioned. Do you have the
    > URL of the page you saw that on?


    According to
    <http://www-128.ibm.com/developerworks/java/library/j-jtp03304/>

    "The original semantics for volatile guaranteed only that reads and writes of
    volatile fields would be made directly to main memory, instead of to registers
    or the local processor cache, ... In other words, this means that the old
    memory model made promises only about the visibility of the variable being
    read or written, and no promises about the visibility of writes to other
    variables. While this was easier to implement efficiently, it turned out to be
    less useful than initially thought.
    "...
    "The JSR 133 Expert Group decided that it would be more sensible for volatile
    reads and writes not to be reorderable with any other memory operations ...
    Under the new memory model, when thread A writes to a volatile variable V, and
    thread B reads from V, any variable values that were visible to A at the time
    that V was written are guaranteed now to be visible to B."

    So it seems that what used to be is now better.

    - Lew
    Lew, Feb 14, 2007
    #5
  6. mei

    Eric Sosman Guest

    Knute Johnson wrote:
    > Eric Sosman wrote:
    >> mei wrote On 02/13/07 14:26,:
    >>> Hi,
    >>> While reading the tutorial
    >>> http://java.sun.com/docs/books/tutorial/essential/concurrency/index.html,
    >>>
    >>> something caught my attention:
    >>> It is said that memory consistency errors can occur even when
    >>> atomicity of reading/writing access is guaranteed with volatile.
    >>> However they don't develop this matter.
    >>> Is there somebody that could explain me more how could this happen?
    >>> Thank in advance.

    >>
    >> Accesses to main memory might not occur in the same
    >> order that the CPU initiated them, particularly for writes
    >> (which often go through hardware write buffers so the CPU
    >> needn't wait for them). If CPU 1 writes the Answer to
    >> location A and then writes the AnswerIsReady flag to B,
    >> CPU 2 may see the change to B before it sees the change
    >> to A, and thus get the WrongAnswer. Making either or both
    >> writes atomic doesn't help; what's needed is something
    >> called a "memory barrier."
    >>

    >
    > Is that not what you get with volatile?


    Hmmm... <browses the specifications, scratches head, gets
    splinters under fingernails>. Perhaps it is. It seems the
    precise meaning of `volatile' has undergone some changes, and
    that the memory-ordering semantics are now tighter than they
    used to be. (See Lew's post on this thread for an informative
    quote.)

    mei, my answer is correct (I think) for older Java versions,
    but is wrong for the latest versions. I apologize for the
    out-of-date information.

    --
    Eric Sosman
    lid
    Eric Sosman, Feb 14, 2007
    #6
  7. Lew wrote:
    > mei wrote:
    >>> Hi,
    >>> While reading the tutorial
    >>> http://java.sun.com/docs/books/tutorial/essential/concurrency/index.html,
    >>>
    >>> something caught my attention:
    >>> It is said that memory consistency errors can occur even when
    >>> atomicity of reading/writing access is guaranteed with volatile.
    >>> However they don't develop this matter.
    >>> Is there somebody that could explain me more how could this happen?
    >>> Thank in advance.

    >
    > Knute Johnson wrote:
    >> I looked and couldn't find the reference you mentioned. Do you have
    >> the URL of the page you saw that on?

    >
    > According to
    > <http://www-128.ibm.com/developerworks/java/library/j-jtp03304/>
    >
    > "The original semantics for volatile guaranteed only that reads and
    > writes of volatile fields would be made directly to main memory, instead
    > of to registers or the local processor cache, ... In other words, this
    > means that the old memory model made promises only about the visibility
    > of the variable being read or written, and no promises about the
    > visibility of writes to other variables. While this was easier to
    > implement efficiently, it turned out to be less useful than initially
    > thought.
    > "...
    > "The JSR 133 Expert Group decided that it would be more sensible for
    > volatile reads and writes not to be reorderable with any other memory
    > operations ... Under the new memory model, when thread A writes to a
    > volatile variable V, and thread B reads from V, any variable values that
    > were visible to A at the time that V was written are guaranteed now to
    > be visible to B."
    >
    > So it seems that what used to be is now better.
    >
    > - Lew


    Lew:

    That's an excellent article, thanks for finding that.

    --

    Knute Johnson
    email s/nospam/knute/
    Knute Johnson, Feb 14, 2007
    #7
  8. Eric Sosman wrote:
    > Knute Johnson wrote:
    >> Eric Sosman wrote:
    >>> mei wrote On 02/13/07 14:26,:
    >>>> Hi,
    >>>> While reading the tutorial
    >>>> http://java.sun.com/docs/books/tutorial/essential/concurrency/index.html,
    >>>>
    >>>> something caught my attention:
    >>>> It is said that memory consistency errors can occur even when
    >>>> atomicity of reading/writing access is guaranteed with volatile.
    >>>> However they don't develop this matter.
    >>>> Is there somebody that could explain me more how could this happen?
    >>>> Thank in advance.
    >>>
    >>> Accesses to main memory might not occur in the same
    >>> order that the CPU initiated them, particularly for writes
    >>> (which often go through hardware write buffers so the CPU
    >>> needn't wait for them). If CPU 1 writes the Answer to
    >>> location A and then writes the AnswerIsReady flag to B,
    >>> CPU 2 may see the change to B before it sees the change
    >>> to A, and thus get the WrongAnswer. Making either or both
    >>> writes atomic doesn't help; what's needed is something
    >>> called a "memory barrier."
    >>>

    >>
    >> Is that not what you get with volatile?

    >
    > Hmmm... <browses the specifications, scratches head, gets
    > splinters under fingernails>. Perhaps it is. It seems the
    > precise meaning of `volatile' has undergone some changes, and
    > that the memory-ordering semantics are now tighter than they
    > used to be. (See Lew's post on this thread for an informative
    > quote.)
    >
    > mei, my answer is correct (I think) for older Java versions,
    > but is wrong for the latest versions. I apologize for the
    > out-of-date information.
    >


    Thanks Eric.

    --

    Knute Johnson
    email s/nospam/knute/
    Knute Johnson, Feb 14, 2007
    #8
  9. mei

    Chris Uppal Guest

    Lew wrote:

    > According to
    > <http://www-128.ibm.com/developerworks/java/library/j-jtp03304/>

    [...]
    > "The JSR 133 Expert Group decided that it would be more sensible for
    > volatile reads and writes not to be reorderable with any other memory
    > operations ... Under the new memory model, when thread A writes to a
    > volatile variable V, and thread B reads from V, any variable values that
    > were visible to A at the time that V was written are guaranteed now to be
    > visible to B."


    Can anyone point me to the passages in JLS3 which imply that. My own study of
    the new stuff has been patchy (and reluctant), but I haven't yet seen anything
    to make the following wrong. (I'm not claiming it /isn't/ wrong, only asking
    for corroboration, or -- better -- refutation).

    With the above caveat. Given a non-local volatile variable:

    volatile int[] volatileField;

    It seems to me that if one thread does the following:

    int[] local = new array[2];
    local[0] = 100;
    local[1] = 200;
    volatileField = local;

    then there are only so many things that another thread, subsequently reading
    the volatileField's contents, is guaranteed to see.

    I believe the following to be guaranteed:

    volatileField is not null.
    volatileField refers to an int[] array of length 2.
    volatileField[0] is either 0 or 100
    volatileField[1] is either 0 or 200

    However, I haven't yet found anything to convince me that any of the following
    are illegal:

    volatileField[0] == 0 && volatileField[1] == 0
    volatileField[0] == 100 && volatileField[1] == 0
    volatileField[0] == 0 && volatileField[1] == 200
    volatileField[0] == 100 && volatileField[1] == 200

    The wording in JLS3 seems to be quite specific about the happens
    before-relationship[*] as it applies to volatiles, and it only seems to refer
    to the value of the volatile /itself/, not to any other actions.

    It may be that the later stuff (causality, etc) in the JLS3 clears this up, but
    as far at the HB relation goes, I can't see that the visible contents of the
    array are fully constrained.

    -- chris

    [*] which I think would be better named: must-not-be-seen-to-happen-after.
    Chris Uppal, Feb 14, 2007
    #9
  10. mei

    mei Guest

    Knute Johnson a écrit :
    > mei wrote:
    >> Hi,
    >> While reading the tutorial
    >> http://java.sun.com/docs/books/tutorial/essential/concurrency/index.html,
    >> something caught my attention:
    >> It is said that memory consistency errors can occur even when
    >> atomicity of reading/writing access is guaranteed with volatile.
    >> However they don't develop this matter.
    >> Is there somebody that could explain me more how could this happen?
    >> Thank in advance.

    >
    > I looked and couldn't find the reference you mentioned. Do you have the
    > URL of the page you saw that on?
    >
    > Thanks,
    >


    Here it is even though it seems it is outdated:
    http://java.sun.com/docs/books/tutorial/essential/concurrency/atomic.html
    "Atomic actions cannot be interleaved, so they can be used without fear
    of thread interference. However, this does not eliminate all need to
    synchronize atomic actions, because memory consistency errors are still
    possible."
    mei, Feb 14, 2007
    #10
  11. mei

    Lew Guest

    Lew wrote:

    Knute Johnson wrote:
    > Lew:
    >
    > That's an excellent article, thanks for finding that.


    Google is my friend.

    -Lew
    Lew, Feb 14, 2007
    #11
  12. mei

    Lew Guest

    mei wrote:
    > Here it is even though it seems it is outdated:
    > http://java.sun.com/docs/books/tutorial/essential/concurrency/atomic.html
    > "Atomic actions cannot be interleaved, so they can be used without fear
    > of thread interference. However, this does not eliminate all need to
    > synchronize atomic actions, because memory consistency errors are still
    > possible."


    They are talking about "happens-before" relationships.

    - Lew
    Lew, Feb 14, 2007
    #12
  13. mei

    mei Guest

    Lew a écrit :
    > mei wrote:
    >> Here it is even though it seems it is outdated:
    >> http://java.sun.com/docs/books/tutorial/essential/concurrency/atomic.html
    >> "Atomic actions cannot be interleaved, so they can be used without
    >> fear of thread interference. However, this does not eliminate all need
    >> to synchronize atomic actions, because memory consistency errors are
    >> still possible."

    >
    > They are talking about "happens-before" relationships.
    >
    > - Lew


    Ok, you are right: As far as I understand it, what the Sun tutorial
    explains about the happens-before relationship matches with what is said
    in the IBM article. Thus the tutorial is also up-to-date.
    But still the tutorial claims that this new semantic of volatile is not
    enough to prevent from memory consistency errors. So I think my initial
    question is still unanswered, or am I missing something?
    mei, Feb 14, 2007
    #13
  14. mei

    Lew Guest

    mei wrote:
    > As far as I understand it, what the Sun tutorial
    > explains about the happens-before relationship matches with what is said
    > in the IBM article. Thus the tutorial is also up-to-date.
    > But still the tutorial claims that this new semantic of volatile is not
    > enough to prevent from memory consistency errors. So I think my initial
    > question is still unanswered, or am I missing something?


    See Chris Uppal's answer in this thread. It includes an example of what might
    be inconsistent.

    - Lew
    Lew, Feb 14, 2007
    #14
  15. Chris Uppal wrote:
    > Lew wrote:
    >
    >> According to
    >> <http://www-128.ibm.com/developerworks/java/library/j-jtp03304/>

    > [...]
    >> "The JSR 133 Expert Group decided that it would be more sensible for
    >> volatile reads and writes not to be reorderable with any other memory
    >> operations ... Under the new memory model, when thread A writes to a
    >> volatile variable V, and thread B reads from V, any variable values that
    >> were visible to A at the time that V was written are guaranteed now to be
    >> visible to B."

    >
    > Can anyone point me to the passages in JLS3 which imply that. My own study of
    > the new stuff has been patchy (and reluctant), but I haven't yet seen anything
    > to make the following wrong. (I'm not claiming it /isn't/ wrong, only asking
    > for corroboration, or -- better -- refutation).
    >
    > With the above caveat. Given a non-local volatile variable:
    >
    > volatile int[] volatileField;
    >
    > It seems to me that if one thread does the following:
    >
    > int[] local = new array[2];
    > local[0] = 100;
    > local[1] = 200;
    > volatileField = local;
    >
    > then there are only so many things that another thread, subsequently reading
    > the volatileField's contents, is guaranteed to see.
    >
    > I believe the following to be guaranteed:
    >
    > volatileField is not null.
    > volatileField refers to an int[] array of length 2.
    > volatileField[0] is either 0 or 100
    > volatileField[1] is either 0 or 200
    >
    > However, I haven't yet found anything to convince me that any of the following
    > are illegal:
    >
    > volatileField[0] == 0 && volatileField[1] == 0
    > volatileField[0] == 100 && volatileField[1] == 0
    > volatileField[0] == 0 && volatileField[1] == 200
    > volatileField[0] == 100 && volatileField[1] == 200
    >
    > The wording in JLS3 seems to be quite specific about the happens
    > before-relationship[*] as it applies to volatiles, and it only seems to refer
    > to the value of the volatile /itself/, not to any other actions.
    >
    > It may be that the later stuff (causality, etc) in the JLS3 clears this up, but
    > as far at the HB relation goes, I can't see that the visible contents of the
    > array are fully constrained.
    >
    > -- chris
    >
    > [*] which I think would be better named: must-not-be-seen-to-happen-after.
    >
    >


    I think if you look at this situation as class with two int fields
    rather than an int[] you will see that the fields are not volatile
    unless declared so. So while the variable volatileField would indeed
    reference the correct int[] there would be no synchronization of the
    array elements across threads.

    Or at least that is what I think today :). Then again it could all be
    different with arrays.

    --

    Knute Johnson
    email s/nospam/knute/
    Knute Johnson, Feb 15, 2007
    #15
  16. Knute Johnson wrote:
    > Chris Uppal wrote:
    >> Lew wrote:
    >>
    >>> According to
    >>> <http://www-128.ibm.com/developerworks/java/library/j-jtp03304/>

    >> [...]
    >>> "The JSR 133 Expert Group decided that it would be more sensible for
    >>> volatile reads and writes not to be reorderable with any other memory
    >>> operations ... Under the new memory model, when thread A writes to a
    >>> volatile variable V, and thread B reads from V, any variable values that
    >>> were visible to A at the time that V was written are guaranteed now
    >>> to be
    >>> visible to B."

    >>
    >> Can anyone point me to the passages in JLS3 which imply that. My own
    >> study of
    >> the new stuff has been patchy (and reluctant), but I haven't yet seen
    >> anything
    >> to make the following wrong. (I'm not claiming it /isn't/ wrong, only
    >> asking
    >> for corroboration, or -- better -- refutation).
    >>
    >> With the above caveat. Given a non-local volatile variable:
    >>
    >> volatile int[] volatileField;
    >>
    >> It seems to me that if one thread does the following:
    >>
    >> int[] local = new array[2];
    >> local[0] = 100;
    >> local[1] = 200;
    >> volatileField = local;
    >>
    >> then there are only so many things that another thread, subsequently
    >> reading
    >> the volatileField's contents, is guaranteed to see.
    >>
    >> I believe the following to be guaranteed:
    >>
    >> volatileField is not null.
    >> volatileField refers to an int[] array of length 2.
    >> volatileField[0] is either 0 or 100
    >> volatileField[1] is either 0 or 200
    >>
    >> However, I haven't yet found anything to convince me that any of the
    >> following
    >> are illegal:
    >>
    >> volatileField[0] == 0 && volatileField[1] == 0
    >> volatileField[0] == 100 && volatileField[1] == 0
    >> volatileField[0] == 0 && volatileField[1] == 200
    >> volatileField[0] == 100 && volatileField[1] == 200
    >>
    >> The wording in JLS3 seems to be quite specific about the happens
    >> before-relationship[*] as it applies to volatiles, and it only seems
    >> to refer
    >> to the value of the volatile /itself/, not to any other actions.
    >>
    >> It may be that the later stuff (causality, etc) in the JLS3 clears
    >> this up, but
    >> as far at the HB relation goes, I can't see that the visible contents
    >> of the
    >> array are fully constrained.
    >>
    >> -- chris
    >>
    >> [*] which I think would be better named:
    >> must-not-be-seen-to-happen-after.
    >>
    >>

    >
    > I think if you look at this situation as class with two int fields
    > rather than an int[] you will see that the fields are not volatile
    > unless declared so. So while the variable volatileField would indeed
    > reference the correct int[] there would be no synchronization of the
    > array elements across threads.
    >
    > Or at least that is what I think today :). Then again it could all be
    > different with arrays.
    >


    And I found some more interesting things. Look at AtomicBoolean in the
    docs and follow the link 'java.util.concurrent.atomic'. It has a
    discussion of the Atomic??? classes and especially see
    AtomicIntegerArray. I still think that it would require synchronization
    to prevent memory consistency errors however.

    --

    Knute Johnson
    email s/nospam/knute/
    Knute Johnson, Feb 15, 2007
    #16
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Mark Goldin

    Errors, errors, errors

    Mark Goldin, Jan 17, 2004, in forum: ASP .Net
    Replies:
    2
    Views:
    939
    Mark Goldin
    Jan 17, 2004
  2. =?Utf-8?B?VkIgQ29kZXI=?=

    Maintain Consistency With ASP.NET Templates

    =?Utf-8?B?VkIgQ29kZXI=?=, Apr 18, 2004, in forum: ASP .Net
    Replies:
    1
    Views:
    439
    aruntjose
    Feb 13, 2006
  3. Replies:
    1
    Views:
    2,009
    slareau
    Nov 17, 2006
  4. Replies:
    0
    Views:
    412
  5. Knute Johnson
    Replies:
    4
    Views:
    1,331
    Knute Johnson
    Jan 30, 2007
Loading...

Share This Page