lkml.org 
[lkml]   [1999]   [Nov]   [25]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    /
    SubjectRe: spin_unlock optimization(i386)
    Date
    From

    Ingo Molnar <mingo@chiara.csoma.elte.hu> wrote:

    ...
    > > If Intel only needed to be atomic, doing the "lock btsl" would not need to
    > > take 22 cycles. The cost comes from being a syncronization barrier, which
    > > is needed to avoid the re-ordering that intel _will_ do.
    >
    > if i was Intel and had the instruction traces they have, maybe i'd have
    > been a wimp as well :) Making LOCK-ed instruction go straight through via
    > just relying on a (hypotetical) internal 'conflict prevention' mechanizm
    > would definitely have been a feat, and would have triggered all the
    > remaining bugs ;)

    I'm pretty sure that we err on the side of paranoia here sometimes. There
    is a LOT of software which depends on us being right, and it's better to
    hedge than to get an extra cycle or two and lose something due to other
    troubles...

    But, it is not needed to avoid any kind of re-ordering that IA32 will
    do. I still maintain that.

    IA32 just doesn't do program visible reordering. Any reordering is
    done only as a performance enhancement and with temporary results that
    are checked prior to becoming committed state.


    ...
    > ok. I think we can actually prove wether reads can even execute noncausal.
    > Lets consider the following code:
    >
    > CPU0 CPU1
    >
    > volatile int i, __fill[8], j; int a, b;
    >
    > i = j = 0;
    >
    > for (;;) { for (;;) {
    > i++; a = i;
    > j++; b = j;
    > } if (a < b)
    > BUG()
    > }
    >
    > (i and j are shared common variables on different cachelines, a and b are
    > local ones)
    >
    > if your theory is true, then 'BUG()' should trigger sooner or later,
    > correct?

    No.

    To guarantee that you've observed the store to "i", you HAVE to read
    the store to "j" first! Plus, your second "for" loop could have blocked
    just after reading "i" into "a", while the first loop could be continuing
    to count upward. "b" could end up with an arbitrarily larger value.

    To make this work correctly in the face of both Processor Ordering
    and pauses in the process execution, the second loop should actually say:

    for (;;) {
    b = j;
    a = i;
    if (a < b)
    BUG();
    }

    With Weak Ordering, this could fail, since you may have not gotten
    all the updates to "i" yet.

    What you know from Processor Ordering is:

    If you see a particular store from processor A, you know you've
    seen all PRIOR stores in program order from processor A.

    This means you have to gate relying on data from another processor until
    you've checked that you have seen kind of "completion event".

    This is exactly what you get with a spinlock situation:

    P0 P1

    X = 0;
    spin_unlock(Y); // does a store to Y

    spin_lock(Y);
    READ X;

    So, P0 does the stores to X, then Y, P1 waits for the store to Y,
    which guarantees P1 will see the right data in X.


    Erich Boleyn
    PMD IA32 Architecture
    Intel

    --
    Erich Boleyn
    PMD Architecture
    <esboleyn@ichips.intel.com>

    -
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.rutgers.edu
    Please read the FAQ at http://www.tux.org/lkml/

    \
     
     \ /
      Last update: 2005-03-22 13:55    [W:2.702 / U:0.016 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site