art of multiprocessor programming - uni-freiburg.de€¦ · art of multiprocessor programming 3...

192
Concurrent Objects Companion slides for The Art of Multiprocessor Programming by Maurice Herlihy & Nir Shavit

Upload: others

Post on 19-Oct-2020

8 views

Category:

Documents


0 download

TRANSCRIPT

  • Concurrent Objects

    Companion slides forThe Art of Multiprocessor

    Programmingby Maurice Herlihy & Nir Shavit

  • Art of Multiprocessor Programming

    2

    Concurrent Computaton

    memory

    object object

  • Art of Multiprocessor Programming

    3

    Objectivism• What is a concurrent object?

    – How do we describe one?– How do we implement one?– How do we tell if we’re right?

  • Art of Multiprocessor Programming

    4

    Objectivism• What is a concurrent object?

    – How do we describe one?

    – How do we tell if we’re right?

  • Art of Multiprocessor Programming

    5

    FIFO Queue: Enqueue Method

    q.enq( )

  • Art of Multiprocessor Programming

    6

    FIFO Queue: Dequeue Method

    q.deq()/

  • Art of Multiprocessor Programming

    7

    A Lock-Based Queueclass LockBasedQueue { int head, tail; T[] items; Lock lock; public LockBasedQueue(int capacity) { head = 0; tail = 0; lock = new ReentrantLock(); items = (T[]) new Object[capacity]; }

  • Art of Multiprocessor Programming

    8

    A Lock-Based Queueclass LockBasedQueue { int head, tail; T[] items; Lock lock; public LockBasedQueue(int capacity) { head = 0; tail = 0; lock = new ReentrantLock(); items = (T[]) new Object[capacity]; }

    0 1capacity-1

    2

    head tail

    y z

    Queue fields protected by single shared lock

  • Art of Multiprocessor Programming

    9

    A Lock-Based Queueclass LockBasedQueue { int head, tail; T[] items; Lock lock; public LockBasedQueue(int capacity) { head = 0; tail = 0; lock = new ReentrantLock(); items = (T[]) new Object[capacity]; }

    0 1capacity-1

    2

    head tail

    y z

    Initially head = tail

  • Art of Multiprocessor Programming

    10

    Implementation: Deqpublic T deq() throws EmptyException { lock.lock(); try { if (tail == head) throw new EmptyException(); T x = items[head % items.length]; head++; return x; } finally { lock.unlock(); } }

    0 1capacity-1

    2

    head tail

    y z

  • Art of Multiprocessor Programming

    11

    Implementation: Deqpublic T deq() throws EmptyException { lock.lock(); try { if (tail == head) throw new EmptyException(); T x = items[head % items.length]; head++; return x; } finally { lock.unlock(); } }

    Method calls mutually exclusive

    0 1capacity-1

    2

    head tail

    y z

  • Art of Multiprocessor Programming

    12

    Implementation: Deqpublic T deq() throws EmptyException { lock.lock(); try { if (tail == head) throw new EmptyException(); T x = items[head % items.length]; head++; return x; } finally { lock.unlock(); } }

    If queue emptythrow exception

    0 1capacity-1

    2

    head tail

    y z

  • Art of Multiprocessor Programming

    13

    Implementation: Deqpublic T deq() throws EmptyException { lock.lock(); try { if (tail == head) throw new EmptyException(); T x = items[head % items.length]; head++; return x; } finally { lock.unlock(); } }

    Queue not empty:remove item and

    update head

    0 1capacity-1

    2

    head tail

    y z

  • Art of Multiprocessor Programming

    14

    Implementation: Deqpublic T deq() throws EmptyException { lock.lock(); try { if (tail == head) throw new EmptyException(); T x = items[head % items.length]; head++; return x; } finally { lock.unlock(); } }

    Return result

    0 1capacity-1

    2

    head tail

    y z

  • Art of Multiprocessor Programming

    15

    Implementation: Deqpublic T deq() throws EmptyException { lock.lock(); try { if (tail == head) throw new EmptyException(); T x = items[head % items.length]; head++; return x; } finally { lock.unlock(); } } Release lock no matter

    what!

    0 1capacity-1

    2

    head tail

    y z

  • Art of Multiprocessor Programming

    16

    Implementation: Deqpublic T deq() throws EmptyException { lock.lock(); try { if (tail == head) throw new EmptyException(); T x = items[head % items.length]; head++; return x; } finally { lock.unlock(); } }

    Should be

    correct b

    ecause

    modifica

    tions are

    mutually

    exclusive…

  • Art of Multiprocessor Programming

    17

    Now consider the following implementation

    • The same thing without mutual exclusion

    • For simplicity, only two threads – One thread enq only– The other deq only

  • Art of Multiprocessor Programming

    18

    Wait-free 2-Thread Queuepublic class WaitFreeQueue {

    int head = 0, tail = 0; items = (T[]) new Object[capacity];

    public void enq(Item x) { while (tail-head == capacity); // busy-wait items[tail % capacity] = x; tail++; } public Item deq() { while (tail == head); // busy-wait Item item = items[head % capacity]; head++; return item;}}

  • Art of Multiprocessor Programming

    19

    Wait-free 2-Thread Queuepublic class LockFreeQueue {

    int head = 0, tail = 0; items = (T[]) new Object[capacity];

    public void enq(Item x) { while (tail-head == capacity); // busy-wait items[tail % capacity] = x; tail++; } public Item deq() { while (tail == head); // busy-wait Item item = items[head % capacity]; head++; return item;}}

    0 1capacity-1

    2

    head tail

    y z

  • Art of Multiprocessor Programming

    20

    Lock-free 2-Thread Queuepublic class LockFreeQueue {

    int head = 0, tail = 0; items = (T[])new Object[capacity];

    public void enq(Item x) { while (tail-head == capacity); // busy-wait items[tail % capacity] = x; tail++; } public Item deq() { while (tail == head); // busy-wait Item item = items[head % capacity]; head++; return item;}}

    0 1capacity-1

    2

    head tail

    y z

    Queue is updated without a lock!How d

    o we defi

    ne

    “correct”

    when

    modifica

    tions are

    not

    mutually e

    xclusive?

  • Art of Multiprocessor Programming

    21

    Defining concurrent queue implementations

    • Need a way to specify a concurrent queue object

    • Need a way to prove that an algorithm implements the object’s specification

    • Lets talk about object specifications …

  • Correctness and Progress• In a concurrent setting, we need to specify

    both the safety and the liveness properties of an object

    • Need a way to define – when an implementation is correct– the conditions under which it guarantees

    progress

    Art of Multiprocessor Programming

    22

    Lets begin with correctness

  • Art of Multiprocessor Programming

    23

    Sequential Objects• Each object has a state

    – Usually given by a set of fields– Queue example: sequence of items

    • Each object has a set of methods– Only way to manipulate state– Queue example: enq and deq

    methods

  • Art of Multiprocessor Programming

    24

    Sequential Specifications• If (precondition)

    – the object is in such-and-such a state– before you call the method,

    • Then (postcondition)– the method will return a particular value– or throw a particular exception.

    • and (postcondition, con’t)– the object will be in some other state– when the method returns,

  • Art of Multiprocessor Programming

    25

    Pre- and Postconditions for Dequeue

    • Precondition:– Queue is non-empty

    • Postcondition:– Returns first item in queue

    • Postcondition:– Removes first item in queue

  • Art of Multiprocessor Programming

    26

    Pre- and Postconditions for Dequeue

    • Precondition:– Queue is empty

    • Postcondition:– Throws Empty exception

    • Postcondition:– Queue state unchanged

  • Art of Multiprocessor Programming

    27

    Why Sequential Specifications Totally Rock

    • Interactions among methods captured by side-effects on object state– State meaningful between method calls

    • Documentation size linear in number of methods– Each method described in isolation

    • Can add new methods– Without changing descriptions of old

    methods

  • Art of Multiprocessor Programming

    28

    What About Concurrent Specifications? x

    • Methods? • Documentation?• Adding new methods?

  • Art of Multiprocessor Programming

    29

    Methods Take Time

    timetime

  • Art of Multiprocessor Programming

    30

    Methods Take Time

    time

    invocation 12:00

    q.enq(...)

    time

  • Art of Multiprocessor Programming

    31

    Methods Take Time

    time

    Method call

    invocation 12:00

    q.enq(...)

    time

  • Art of Multiprocessor Programming

    32

    Methods Take Time

    time

    Method call

    invocation 12:00

    q.enq(...)

    time

  • Art of Multiprocessor Programming

    33

    Methods Take Time

    time

    Method call

    invocation 12:00

    q.enq(...)

    time

    void

    response 12:01

  • Art of Multiprocessor Programming

    34

    Sequential vs Concurrent• Sequential

    – Methods take time? Who knew?• Concurrent

    – Method call is not an event– Method call is an interval.

  • Art of Multiprocessor Programming

    35

    time

    Concurrent Methods Take Overlapping Time

    time

  • Art of Multiprocessor Programming

    36

    time

    Concurrent Methods Take Overlapping Time

    time

    Method call

  • Art of Multiprocessor Programming

    37

    time

    Concurrent Methods Take Overlapping Time

    time

    Method call

    Method call

  • Art of Multiprocessor Programming

    38

    time

    Concurrent Methods Take Overlapping Time

    time

    Method call Method call

    Method call

  • Art of Multiprocessor Programming

    39

    Sequential vs Concurrent• Sequential:

    – Object needs meaningful state only between method calls

    • Concurrent– Because method calls overlap, object

    might never be between method calls

  • Art of Multiprocessor Programming

    40

    Sequential vs Concurrent• Sequential:

    – Each method described in isolation• Concurrent

    – Must characterize all possible interactions with concurrent calls • What if two enqs overlap?• Two deqs? enq and deq? …

  • Art of Multiprocessor Programming

    41

    Sequential vs Concurrent• Sequential:

    – Can add new methods without affecting older methods

    • Concurrent:– Everything can potentially interact

    with everything else

  • Art of Multiprocessor Programming

    42

    Sequential vs Concurrent• Sequential:

    – Can add new methods without affecting older methods

    • Concurrent:– Everything can potentially interact

    with everything else Panic!

  • Art of Multiprocessor Programming

    43

    The Big Question

    • What does it mean for a concurrent object to be correct?– What is a concurrent FIFO queue?– FIFO means strict temporal order– Concurrent means ambiguous

    temporal order

  • Art of Multiprocessor Programming

    44

    Intuitively…public T deq() throws EmptyException { lock.lock(); try { if (tail == head) throw new EmptyException(); T x = items[head % items.length]; head++; return x; } finally { lock.unlock(); } }

  • Art of Multiprocessor Programming

    45

    Intuitively…public T deq() throws EmptyException { lock.lock(); try { if (tail == head) throw new EmptyException(); T x = items[head % items.length]; head++; return x; } finally { lock.unlock(); } }

    All modifications of queue are done mutually exclusive

  • Art of Multiprocessor Programming

    46

    time

    Intuitivelyq.deq

    q.enq

    enq deq

    lock() unlock()

    lock() unlock() Behavior is “Sequential”

    enq

    deq

    Lets capture the idea of describing the concurrent via the sequential

  • Art of Multiprocessor Programming

    47

    Linearizability• Each method should

    – “take effect”– Instantaneously– Between invocation and response

    events• Object is correct if this “sequential”

    behavior is correct• Any such concurrent object is

    – Linearizable™

  • Art of Multiprocessor Programming

    48

    Is it really about the object? x

    • Each method should– “take effect”– Instantaneously– Between invocation and response events

    • Sounds like a property of an execution…• A linearizable object: one all of whose

    possible executions are linearizable

  • Art of Multiprocessor Programming

    49

    Example

    timetime

    (6)

  • Art of Multiprocessor Programming

    50

    Example

    time

    q.enq(x)

    time

    (6)

  • Art of Multiprocessor Programming

    51

    Example

    time

    q.enq(x)

    q.enq(y)

    time

    (6)

  • Art of Multiprocessor Programming

    52

    Example

    time

    q.enq(x)

    q.enq(y) q.deq(x)

    time

    (6)

  • Art of Multiprocessor Programming

    53

    Example

    time

    q.enq(x)

    q.enq(y) q.deq(x)

    q.deq(y)

    time

    (6)

  • Art of Multiprocessor Programming

    54

    Example

    time

    q.enq(x)

    q.enq(y) q.deq(x)

    q.deq(y)

    linearizableq.enq(x)

    q.enq(y) q.deq(x)

    q.deq(y)

    time

    (6)

  • Art of Multiprocessor Programming

    55

    Example

    time

    q.enq(x)

    q.enq(y) q.deq(x)

    q.deq(y)

    Valid?q.enq(x)

    q.enq(y) q.deq(x)

    q.deq(y)

    time

    (6)

  • Art of Multiprocessor Programming

    56

    Example

    time

    (5)

  • Art of Multiprocessor Programming

    57

    Example

    time

    q.enq(x)

    (5)

  • Art of Multiprocessor Programming

    58

    Example

    time

    q.enq(x) q.deq(y)

    (5)

  • Art of Multiprocessor Programming

    59

    Example

    time

    q.enq(x)

    q.enq(y)

    q.deq(y)

    (5)

  • Art of Multiprocessor Programming

    60

    Example

    time

    q.enq(x)

    q.enq(y)

    q.deq(y)q.enq(x)

    q.enq(y)

    (5)

  • Art of Multiprocessor Programming

    61

    Example

    time

    q.enq(x)

    q.enq(y)

    q.deq(y)q.enq(x)

    q.enq(y)

    (5)

    not linearizable

  • Art of Multiprocessor Programming

    62

    Example

    timetime

    (4)

  • Art of Multiprocessor Programming

    63

    Example

    time

    q.enq(x)

    time

    (4)

  • Art of Multiprocessor Programming

    64

    Example

    time

    q.enq(x)

    q.deq(x)

    time

    (4)

  • Art of Multiprocessor Programming

    65

    Example

    time

    q.enq(x)

    q.deq(x)

    q.enq(x)

    q.deq(x)

    time

    (4)

  • Art of Multiprocessor Programming

    66

    Example

    time

    q.enq(x)

    q.deq(x)

    q.enq(x)

    q.deq(x)

    linearizable

    time

    (4)

  • Art of Multiprocessor Programming

    67

    Example

    time

    q.enq(x)

    time

    (8)

  • Art of Multiprocessor Programming

    68

    Example

    time

    q.enq(x)

    q.enq(y)

    time

    (8)

  • Art of Multiprocessor Programming

    69

    Example

    time

    q.enq(x)

    q.enq(y)

    q.deq(y)

    time

    (8)

  • Art of Multiprocessor Programming

    70

    Example

    time

    q.enq(x)

    q.enq(y)

    q.deq(y)

    q.deq(x)

    time

    (8)

  • Art of Multiprocessor Programming

    71

    q.enq(x)

    q.enq(y)

    q.deq(y)

    q.deq(x)

    Comme ci Example

    time

    Comme ça multiple orders

    OKlinearizable

  • Art of Multiprocessor Programming

    72

    Read/Write Register Example

    time

    read(1)write(0)

    write(1)

    write(2)

    time

    read(0)

    (4)

  • Art of Multiprocessor Programming

    73

    Read/Write Register Example

    time

    read(1)write(0)

    write(1)

    write(2)

    time

    read(0)write(1) already

    happened(4)

  • Art of Multiprocessor Programming

    74

    Read/Write Register Example

    time

    read(1)write(0)

    write(1)

    write(2)

    time

    read(0)write(1)write(1) already

    happened(4)

  • Art of Multiprocessor Programming

    75

    Read/Write Register Example

    time

    read(1)write(0)

    write(1)

    write(2)

    time

    read(0)write(1)write(1) already

    happened(4)

    not linearizable

  • Art of Multiprocessor Programming

    76

    Read/Write Register Example

    time

    read(1)write(0)

    write(1)

    write(2)

    time

    read(1)write(1) already

    happened(4)

  • Art of Multiprocessor Programming

    77

    Read/Write Register Example

    time

    read(1)write(0)

    write(1)

    write(2)

    time

    read(1)write(1)

    write(2)

    (4)

    write(1) already

    happened

  • Art of Multiprocessor Programming

    78

    Read/Write Register Example

    time

    read(1)write(0)

    write(1)

    write(2)

    time

    read(1)write(1)

    write(2)

    not linearizable

    (4)

    write(1) already

    happened

  • Art of Multiprocessor Programming

    79

    Read/Write Register Example

    time

    write(0)

    write(1)

    write(2)

    time

    read(1)

    (4)

  • Art of Multiprocessor Programming

    80

    Read/Write Register Example

    time

    write(0)

    write(1)

    write(2)

    time

    read(1)write(1)

    write(2)

    (4)

  • Art of Multiprocessor Programming

    81

    Read/Write Register Example

    time

    write(0)

    write(1)

    write(2)

    time

    read(1)write(1)

    write(2)

    linearizable

    (4)

  • Art of Multiprocessor Programming

    82

    Read/Write Register Example

    time

    read(1)write(0)

    write(1)

    write(2)

    time

    read(1)

    (2)

  • Art of Multiprocessor Programming

    83

    Read/Write Register Example

    time

    read(1)write(0)

    write(1)

    write(2)

    time

    read(1)write(1)

    (2)

  • Art of Multiprocessor Programming

    84

    Read/Write Register Example

    time

    read(1)write(0)

    write(1)

    write(2)

    time

    read(1)write(1)

    write(2)

    (2)

  • Art of Multiprocessor Programming

    85

    Read/Write Register Example

    time

    read(1)write(0)

    write(1)

    write(2)

    time

    read(2)write(1)

    write(2)

    Not linearizable

    (2)

  • Art of Multiprocessor Programming

    86

    Talking About Executions• Why?

    – Can’t we specify the linearization point of each operation without describing an execution?

    • Not Always– In some cases, linearization point

    depends on the execution

  • Art of Multiprocessor Programming

    87

    Formal Model of Executions

    • Define precisely what we mean– Ambiguity is bad when intuition is weak

    • Allow reasoning– Formal– But mostly informal

    • In the long run, actually more important• Ask me why!

  • Art of Multiprocessor Programming

    88

    Split Method Calls into Two Events

    • Invocation– method name & args– q.enq(x)

    • Response– result or exception– q.enq(x) returns void– q.deq() returns x– q.deq() throws empty

  • Art of Multiprocessor Programming

    89

    Invocation Notation

    A q.enq(x)

    (4)

  • Art of Multiprocessor Programming

    90

    Invocation Notation

    A q.enq(x)

    thread

    (4)

  • Art of Multiprocessor Programming

    91

    Invocation Notation

    A q.enq(x)

    thread method

    (4)

  • Art of Multiprocessor Programming

    92

    Invocation Notation

    A q.enq(x)

    thread

    object(4)

    method

  • Art of Multiprocessor Programming

    93

    Invocation Notation

    A q.enq(x)

    thread

    object

    method

    arguments(4)

  • Art of Multiprocessor Programming

    94

    Response Notation

    A q: void

    (2)

  • Art of Multiprocessor Programming

    95

    Response Notation

    A q: void

    thread

    (2)

  • Art of Multiprocessor Programming

    96

    Response Notation

    A q: void

    thread result

    (2)

  • Art of Multiprocessor Programming

    97

    Response Notation

    A q: void

    thread

    object

    result

    (2)

  • Art of Multiprocessor Programming

    98

    Response Notation

    A q: void

    thread

    object

    result

    (2)

    Meth

    od is

    impli

    cit

  • Art of Multiprocessor Programming

    99

    Response Notation

    A q: empty()

    thread

    object(2)

    Meth

    od is

    impli

    cit

    exception

  • Art of Multiprocessor Programming

    100

    History - Describing an Execution

    A q.enq(3)A q:voidA q.enq(5)B p.enq(4)B p:voidB q.deq()B q:3

    Sequence of invocations and

    responses

    H =

  • Art of Multiprocessor Programming

    101

    Definition• Invocation & response match if

    A q.enq(3)

    A q:void

    Thread names agree

    Object names agree

    Method call

    (1)

  • Art of Multiprocessor Programming

    102

    Object Projections

    A q.enq(3)A q:voidB p.enq(4)B p:voidB q.deq()B q:3

    H =

  • Art of Multiprocessor Programming

    103

    Object Projections

    A q.enq(3)A q:voidB p.enq(4)B p:voidB q.deq()B q:3

    H|q =

  • Art of Multiprocessor Programming

    104

    Thread Projections

    A q.enq(3)A q:voidB p.enq(4)B p:voidB q.deq()B q:3

    H =

  • Art of Multiprocessor Programming

    105

    Thread Projections

    A q.enq(3)A q:voidB p.enq(4)B p:voidB q.deq()B q:3

    H|B =

  • Art of Multiprocessor Programming

    106

    Complete Subhistory

    A q.enq(3)A q:voidA q.enq(5)B p.enq(4)B p:voidB q.deq()B q:3

    An invocation is pending if it has

    no matching respnse

    H =

  • Art of Multiprocessor Programming

    107

    Complete Subhistory

    A q.enq(3)A q:voidA q.enq(5)B p.enq(4)B p:voidB q.deq()B q:3

    May or may not have taken

    effect

    H =

  • Art of Multiprocessor Programming

    108

    Complete Subhistory

    A q.enq(3)A q:voidA q.enq(5)B p.enq(4)B p:voidB q.deq()B q:3

    discard pending invocations

    H =

  • Art of Multiprocessor Programming

    109

    Complete Subhistory

    A q.enq(3)A q:void B p.enq(4)B p:voidB q.deq()B q:3

    Complete(H) =

  • Art of Multiprocessor Programming

    110

    Sequential Histories

    A q.enq(3)A q:voidB p.enq(4)B p:voidB q.deq()B q:3A q:enq(5)

    (4)

  • Art of Multiprocessor Programming

    111

    Sequential Histories

    A q.enq(3)A q:voidB p.enq(4)B p:voidB q.deq()B q:3A q:enq(5)

    match

    (4)

  • Art of Multiprocessor Programming

    112

    Sequential Histories

    A q.enq(3)A q:voidB p.enq(4)B p:voidB q.deq()B q:3A q:enq(5)

    match

    match

    (4)

  • Art of Multiprocessor Programming

    113

    Sequential Histories

    A q.enq(3)A q:voidB p.enq(4)B p:voidB q.deq()B q:3A q:enq(5)

    match

    match

    match

    (4)

  • Art of Multiprocessor Programming

    114

    Sequential Histories

    A q.enq(3)A q:voidB p.enq(4)B p:voidB q.deq()B q:3A q:enq(5)

    match

    match

    match

    Final pending invocation OK

    (4)

  • Art of Multiprocessor Programming

    115

    Sequential Histories

    A q.enq(3)A q:voidB p.enq(4)B p:voidB q.deq()B q:3A q:enq(5)

    match

    match

    match

    Final pending invocation OK

    (4)

    Method calls of

    different threads

    do not interleave

  • Art of Multiprocessor Programming

    116

    Well-Formed Histories

    H=

    A q.enq(3)B p.enq(4)B p:voidB q.deq()A q:voidB q:3

  • Art of Multiprocessor Programming

    117

    Well-Formed Histories

    H=

    A q.enq(3)B p.enq(4)B p:voidB q.deq()A q:voidB q:3

    H|B=B p.enq(4)B p:voidB q.deq()B q:3

    Per-thread projections sequential

  • Art of Multiprocessor Programming

    118

    Well-Formed Histories

    H=

    A q.enq(3)B p.enq(4)B p:voidB q.deq()A q:voidB q:3

    H|B=B p.enq(4)B p:voidB q.deq()B q:3

    A q.enq(3)A q:void

    H|A=

    Per-thread projections sequential

  • Art of Multiprocessor Programming

    119

    Equivalent Histories

    H=

    A q.enq(3)B p.enq(4)B p:voidB q.deq()A q:voidB q:3

    Threads see the same thing in both

    A q.enq(3)A q:voidB p.enq(4)B p:voidB q.deq()B q:3

    G=

    H|A = G|AH|B = G|B

  • Art of Multiprocessor Programming

    120

    Sequential Specifications• A sequential specification is some

    way of telling whether a– Single-thread, single-object history– Is legal

    • For example:– Pre and post-conditions– But plenty of other techniques exist …

  • Art of Multiprocessor Programming

    121

    Legal Histories• A sequential (multi-object) history

    H is legal if– For every object x– H|x is in the sequential spec for x

  • Art of Multiprocessor Programming

    122

    Precedence

    A q.enq(3)B p.enq(4)B p.voidA q:voidB q.deq()B q:3

    A method call precedes another if

    response event precedes invocation

    event

    Method call Method call

    (1)

  • Art of Multiprocessor Programming

    123

    Non-Precedence

    A q.enq(3)B p.enq(4)B p.voidB q.deq()A q:voidB q:3

    Some method calls overlap one

    anotherMethod call

    Method call

    (1)

  • Art of Multiprocessor Programming

    124

    Notation• Given

    – History H– method executions m0 and m1 in H

    • We say m0 H m1, if– m0 precedes m1

    • Relation m0 H m1 is a– Partial order – Total order if H is sequential

    m0 m1

  • Art of Multiprocessor Programming

    125

    Linearizability• History H is linearizable if it can

    be extended to G by– Appending zero or more responses to

    pending invocations– Discarding other pending invocations

    • So that G is equivalent to– Legal sequential history S – where G ⊂ S

  • Art of Multiprocessor Programming

    126

    What is G ⊂ S

    time

    a

    b

    time

    (8)

    G

    S

    cG

    G = {ac,bc}S = {ab,ac,bc}

    A limi

    tation

    on th

    e

    Choice

    of S!

  • Art of Multiprocessor Programming

    127

    Remarks• Some pending invocations

    – Took effect, so keep them– Discard the rest

    • Condition G ⊂ S– Means that S respects “real-time

    order” of G

  • Art of Multiprocessor Programming

    128

    A q.enq(3)B q.enq(4)B q:voidB q.deq()B q:4B q:enq(6)

    Example

    time

    B.q.enq(4)

    A. q.enq(3)

    B.q.deq(4) B. q.enq(6)

  • Art of Multiprocessor Programming

    129

    Example

    Complete this pending

    invocation

    time

    B.q.enq(4) B.q.deq(3) B. q.enq(6)

    A q.enq(3)B q.enq(4)B q:voidB q.deq()B q:4B q:enq(6)

    A. q.enq(3)

  • Art of Multiprocessor Programming

    130

    Example

    Complete this pending

    invocation

    time

    B.q.enq(4) B.q.deq(4) B. q.enq(6)

    B.q.enq(3)

    A q.enq(3)B q.enq(4)B q:voidB q.deq()B q:4B q:enq(6)A q:void

  • Art of Multiprocessor Programming

    131

    Example

    time

    B.q.enq(4) B.q.deq(4) B. q.enq(6)

    B.q.enq(3)

    A q.enq(3)B q.enq(4)B q:voidB q.deq()B q:4B q:enq(6)A q:void

    discard this one

  • Art of Multiprocessor Programming

    132

    Example

    time

    B.q.enq(4) B.q.deq(4)

    B.q.enq(3)

    A q.enq(3)B q.enq(4)B q:voidB q.deq()B q:4

    A q:void

    discard this one

  • Art of Multiprocessor Programming

    133

    A q.enq(3)B q.enq(4)B q:voidB q.deq()B q:4A q:void

    Example

    time

    B.q.enq(4) B.q.deq(4)

    B.q.enq(3)

  • Art of Multiprocessor Programming

    134

    A q.enq(3)B q.enq(4)B q:voidB q.deq()B q:4A q:void

    Example

    time

    B q.enq(4)B q:voidA q.enq(3)A q:voidB q.deq()B q:4

    B.q.enq(4) B.q.deq(4)

    B.q.enq(3)

  • Art of Multiprocessor Programming

    135

    B.q.enq(4) B.q.deq(4)

    B.q.enq(3)

    A q.enq(3)B q.enq(4)B q:voidB q.deq()B q:4A q:void

    Example

    time

    B q.enq(4)B q:voidA q.enq(3)A q:voidB q.deq()B q:4

    Equivalent sequential history

  • Art of Multiprocessor Programming

    136

    Concurrency• How much concurrency does

    linearizability allow?• When must a method invocation

    block?

  • Art of Multiprocessor Programming

    137

    Concurrency• Focus on total methods

    – Defined in every state• Example:

    – deq() that throws Empty exception– Versus deq() that waits …

    • Why?– Otherwise, blocking unrelated to

    synchronization

  • Art of Multiprocessor Programming

    138

    Concurrency• Question: When does linearizability

    require a method invocation to block?

    • Answer: never.• Linearizability is non-blocking

  • Art of Multiprocessor Programming

    139

    Non-Blocking TheoremIf method invocation

    A q.inv(…)is pending in history H, then there

    exists a responseA q:res(…)

    such thatH + A q:res(…)

    is linearizable

  • Art of Multiprocessor Programming

    140

    Proof• Pick linearization S of H• If S already contains

    – Invocation A q.inv(…) and response,– Then we are done.

    • Otherwise, pick a response such that– S + A q.inv(…) + A q:res(…) – Possible because object is total.

  • Art of Multiprocessor Programming

    141

    Composability Theorem• History H is linearizable if and only

    if– For every object x– H|x is linearizable

    • We care about objects only!– (Materialism?)

  • Art of Multiprocessor Programming

    142

    Why Does Composability Matter?

    • Modularity • Can prove linearizability of objects

    in isolation• Can compose independently-

    implemented objects

  • Art of Multiprocessor Programming

    143

    Reasoning About Linearizability: Locking

    public T deq() throws EmptyException { lock.lock(); try { if (tail == head) throw new EmptyException(); T x = items[head % items.length]; head++; return x; } finally { lock.unlock(); } }

    0 1capacity-1

    2

    head tail

    y z

  • Art of Multiprocessor Programming

    144

    Reasoning About Linearizability: Locking

    public T deq() throws EmptyException { lock.lock(); try { if (tail == head) throw new EmptyException(); T x = items[head % items.length]; head++; return x; } finally { lock.unlock(); } }

    Linearization pointsare when locks are

    released

  • Art of Multiprocessor Programming

    145

    More Reasoning: Lock-free public class LockFreeQueue {

    int head = 0, tail = 0; items = (T[]) new Object[capacity];

    public void enq(Item x) { while (tail-head == capacity); // busy-wait items[tail % capacity] = x; tail++; } public Item deq() { while (tail == head); // busy-wait Item item = items[head % capacity]; head++; return item;}}

    0 1capacity-1

    2

    head tail

    y z

  • Art of Multiprocessor Programming

    146

    public class LockFreeQueue {

    int head = 0, tail = 0; items = (T[]) new Object[capacity];

    public void enq(Item x) { while (tail-head == capacity); // busy-wait items[tail % capacity] = x; tail++; } public Item deq() { while (tail == head); // busy-wait Item item = items[head % capacity]; head++; return item;}}

    Linearization order is order head and tail fields modified

    More Reasoning

    Reme

    mber

    that t

    here

    is on

    ly on

    e enq

    ueue

    r

    and o

    nly on

    e deq

    ueue

    r

  • Art of Multiprocessor Programming

    147

    Strategy• Identify one atomic step where

    method “happens”– Critical section– Machine instruction

    • Doesn’t always work– Might need to define several different

    steps for a given method

  • Art of Multiprocessor Programming

    148

    Linearizability: Summary• Powerful specification tool for

    shared objects• Allows us to capture the notion of

    objects being “atomic”• Don’t leave home without it

  • Art of Multiprocessor Programming

    149

    Alternative: Sequential Consistency

    • History H is Sequentially Consistent if it can be extended to G by– Appending zero or more responses to

    pending invocations– Discarding other pending invocations

    • So that G is equivalent to a– Legal sequential history S – Where G ⊂ S

    Differs from linearizability

  • Art of Multiprocessor Programming

    150

    Alternative: Sequential Consistency

    • No need to preserve real-time order– Cannot re-order operations done by the

    same thread– Can re-order non-overlapping operations

    done by different threads• Often used to describe multiprocessor

    memory architectures

  • Art of Multiprocessor Programming

    151

    Example

    time

    (5)

  • Art of Multiprocessor Programming

    152

    Example

    time

    q.enq(x)

    (5)

  • Art of Multiprocessor Programming

    153

    Example

    time

    q.enq(x) q.deq(y)

    (5)

  • Art of Multiprocessor Programming

    154

    Example

    time

    q.enq(x)

    q.enq(y)

    q.deq(y)

    (5)

  • Art of Multiprocessor Programming

    155

    Example

    time

    q.enq(x)

    q.enq(y)

    q.deq(y)q.enq(x)

    q.enq(y)

    (5)

  • Art of Multiprocessor Programming

    156

    Example

    time

    q.enq(x)

    q.enq(y)

    q.deq(y)q.enq(x)

    q.enq(y)

    (5)

    not linearizable

  • Art of Multiprocessor Programming

    157

    Example

    time

    q.enq(x)

    q.enq(y)

    q.deq(y)q.enq(x)

    q.enq(y)

    (5)

    Yet Sequentially

    Consistent

  • Art of Multiprocessor Programming

    158

    Theorem

    Sequential Consistency is not a local property

    (and thus we lose composability…)

  • Art of Multiprocessor Programming

    159

    FIFO Queue Example

    time

    p.enq(x) p.deq(y)q.enq(x)

    time

  • Art of Multiprocessor Programming

    160

    FIFO Queue Example

    time

    p.enq(x) p.deq(y)q.enq(x)

    q.enq(y) q.deq(x)p.enq(y)

    time

  • Art of Multiprocessor Programming

    161

    FIFO Queue Example

    time

    p.enq(x) p.deq(y)q.enq(x)

    q.enq(y) q.deq(x)p.enq(y)

    History Htime

  • Art of Multiprocessor Programming

    162

    H|p Sequentially Consistent

    time

    p.enq(x) p.deq(y)

    p.enq(y)

    q.enq(x)

    q.enq(y) q.deq(x)

    time

  • Art of Multiprocessor Programming

    163

    H|q Sequentially Consistent

    time

    p.enq(x) p.deq(y)q.enq(x)

    q.enq(y) q.deq(x)p.enq(y)

    time

  • Art of Multiprocessor Programming

    164

    Ordering imposed by p

    time

    p.enq(x) p.deq(y)q.enq(x)

    q.enq(y) q.deq(x)p.enq(y)

    time

  • Art of Multiprocessor Programming

    165

    Ordering imposed by q

    time

    p.enq(x) p.deq(y)q.enq(x)

    q.enq(y) q.deq(x)p.enq(y)

    time

  • Art of Multiprocessor Programming

    166

    p.enq(x)

    Ordering imposed by both

    time

    q.enq(x)

    q.enq(y) q.deq(x)

    time

    p.deq(y)

    p.enq(y)

  • Art of Multiprocessor Programming

    167

    p.enq(x)

    Combining orders

    time

    q.enq(x)

    q.enq(y) q.deq(x)

    time

    p.deq(y)

    p.enq(y)

  • Art of Multiprocessor Programming

    168

    Fact• Most hardware architectures don’t

    support sequential consistency• Because they think it’s too strong• Here’s another story …

  • Art of Multiprocessor Programming

    169

    The Flag Example

    time

    x.write(1) y.read(0)

    y.write(1) x.read(0)

    time

  • Art of Multiprocessor Programming

    170

    The Flag Example

    time

    x.write(1) y.read(0)

    y.write(1) x.read(0)

    • Each thread’s view is sequentially consistent– It went first

  • Art of Multiprocessor Programming

    171

    The Flag Example

    time

    x.write(1) y.read(0)

    y.write(1) x.read(0)

    • Entire history isn’t sequentially consistent– Can’t both go first

  • Art of Multiprocessor Programming

    172

    The Flag Example

    time

    x.write(1) y.read(0)

    y.write(1) x.read(0)

    • Is this behavior really so wrong?– We can argue either way …

  • Art of Multiprocessor Programming

    173

    Opinion1: It’s Wrong• This pattern

    – Write mine, read yours• Is exactly the flag principle

    – Beloved of Alice and Bob– Heart of mutual exclusion

    • Peterson• Bakery, etc.

    • It’s non-negotiable!

  • Art of Multiprocessor Programming

    174

    Opinion2: But It Feels So Right …

    • Many hardware architects think that sequential consistency is too strong

    • Too expensive to implement in modern hardware

    • OK if flag principle– violated by default– Honored by explicit request

  • Art of Multiprocessor Programming

    175

    Memory Hierarchy

    • On modern multiprocessors, processors do not read and write directly to memory.

    • Memory accesses are very slow compared to processor speeds,

    • Instead, each processor reads and writes directly to a cache

  • Art of Multiprocessor Programming

    176

    Memory Operations

    • To read a memory location,– load data into cache.

    • To write a memory location– update cached copy,– Lazily write cached data back to

    memory

  • Art of Multiprocessor Programming

    177

    While Writing to Memory

    • A processor can execute hundreds, or even thousands of instructions

    • Why delay on every memory write?

    • Instead, write back in parallel with rest of the program.

  • Art of Multiprocessor Programming

    178

    Revisionist History• Flag violation history is actually OK

    – processors delay writing to memory– Until after reads have been issued.

    • Otherwise unacceptable delay between read and write instructions.

    • Who knew you wanted to synchronize?

  • Art of Multiprocessor Programming

    179

    Who knew you wanted to synchronize?

    • Writing to memory = mailing a letter• Vast majority of reads & writes

    – Not for synchronization– No need to idle waiting for post office

    • If you want to synchronize– Announce it explicitly– Pay for it only when you need it

  • Art of Multiprocessor Programming

    180

    Explicit Synchronization• Memory barrier instruction

    – Flush unwritten caches– Bring caches up to date

    • Compilers often do this for you– Entering and leaving critical sections

    • Expensive

  • Art of Multiprocessor Programming

    181

    Volatile• In Java, can ask compiler to keep a

    variable up-to-date with volatile keyword

    • Also inhibits reordering, removing from loops, & other “optimizations”

  • Art of Multiprocessor Programming

    182

    Real-World Hardware Memory

    • Weaker than sequential consistency• But you can get sequential consistency

    at a price• OK for expert, tricky stuff

    – assembly language, device drivers, etc.• Linearizability more appropriate for high-

    level software

  • Art of Multiprocessor Programming

    183

    Critical Sections• Easy way to implement

    linearizability– Take sequential object– Make each method a critical section

    • Problems– Blocking– No concurrency

  • Art of Multiprocessor Programming

    184

    Linearizability• Linearizability

    – Operation takes effect instantaneously between invocation and response

    – Uses sequential specification, locality implies composablity

    – Good for high level objects

  • Art of Multiprocessor Programming

    185

    Correctness: Linearizability

    • Sequential Consistency– Not composable– Harder to work with– Good way to think about hardware

    models• We will use linearizability as in the

    remainder of this course unless stated otherwise

  • Progress• We saw an implementation whose

    methods were lock-based (deadlock-free)

    • We saw an implementation whose methods did not use locks (lock-free)

    • How do they relate?

    Art of Multiprocessor Programming

    186

  • Maximal vs. Minimal• Minimal progress: in some suffix of H, some

    pending active invocation has a matching response (some method call eventually completes ).

    • Maximal progress: in every suffix of H, every pending active invocation has a matching response (every method call always completes).

    Art of Multiprocessor Programming

    187

  • Progress Conditions • Deadlock-free: some thread trying to

    acquire the lock eventually succeeds.• Starvation-free: every thread trying to

    acquire the lock eventually succeeds.• Lock-free: some thread calling a method

    eventually returns.• Wait-free: every thread calling a method

    eventually returns.

    Art of Multiprocessor Programming

    188

  • Progress Conditions

    Art of Multiprocessor Programming

    189

    Wait-free

    Lock-free

    Starvation-free

    Deadlock-free

    Everyone makes progress

    Non-Blocking Blocking

    Someone makes progress

  • Art of Multiprocessor Programming

    190

    Summary• We will look at linearizable

    blocking and non-blocking implementations of objects.

  • Fair Histories• A history is fair if each thread always

    continues takes steps.• On multiprocessors this is controlled by

    the operating system…• So fair histories are ones in which the

    operating system guarantees each thread continues to take steps

    Art of Multiprocessor Programming

    191

  • Art of Multiprocessor Programming

    192

             This work is licensed under a Creative Commons Attribution-ShareAlike 2.5 License.

    • You are free:– to Share — to copy, distribute and transmit the work – to Remix — to adapt the work

    • Under the following conditions:– Attribution. You must attribute the work to “The Art of

    Multiprocessor Programming” (but not in any way that suggests that the authors endorse you or your use of the work).

    – Share Alike. If you alter, transform, or build upon this work, you may distribute the resulting work only under the same, similar or a compatible license.

    • For any reuse or distribution, you must make clear to others the license terms of this work. The best way to do this is with a link to– http://creativecommons.org/licenses/by-sa/3.0/.

    • Any of the above conditions can be waived if you get permission from the copyright holder.

    • Nothing in this license impairs or restricts the author's moral rights.

    http://creativecommons.org/licenses/by-sa/2.5/http://creativecommons.org/licenses/by-sa/2.5/http://creativecommons.org/licenses/by-sa/2.5/