Tutorial04 Solution

download Tutorial04 Solution

of 21

Transcript of Tutorial04 Solution

  • 8/12/2019 Tutorial04 Solution

    1/21

    Technische Universitt Mnchen

    Chip Multicore ProcessorsTutorial 4

    Institute for Integrated Systems

    Theresienstr. 90

    Building N1www.lis.ei.tum.de

    S. Wallentowitz

  • 8/12/2019 Tutorial04 Solution

    2/21

    Technische Universitt Mnchen

    Institute for Integrated SystemsChip Multicore Processors

    Tutorial 3

    2

    S. Wallentowitz

    Task 3.2: Locking

    On the right you find a piece of

    source code to implement a

    stack. In a stack, the last written

    element is read as first (LIFO).

    Use the functionsmutex_lock(mutex*) and

    mutex_unlock(mutex*) to

    make the code thread-safe.

    #define N 100

    int buf[N];

    int c=0;

    mutex lock;

    void write(int i) {

    int tmp=c;

    while(tmp==N) {

    tmp=c;

    }

    buf[c]=i;

    c=c+1;

    }

    int read() {

    int r, tmp=c;

    while(tmp==0) {tmp=c;

    }

    r=buf[c];

    c=c-1;

    return r;

    }

  • 8/12/2019 Tutorial04 Solution

    3/21

    Technische Universitt Mnchen

    Institute for Integrated SystemsChip Multicore Processors

    Tutorial 3

    3

    S. Wallentowitz

    void write(int i) {

    int tmp

    tmp=c;

    while(tmp==N) {

    tmp=c;

    }

    buf[c]=i;

    c=c+1;}

  • 8/12/2019 Tutorial04 Solution

    4/21

    Technische Universitt Mnchen

    Institute for Integrated SystemsChip Multicore Processors

    Tutorial 3

    4

    S. Wallentowitz

    int read() {

    int r, tmp

    tmp = c;

    while(tmp==0) {

    tmp=c;}

    r=buf[c];

    c=c-1;

    return r;

    }

  • 8/12/2019 Tutorial04 Solution

    5/21

    Technische Universitt Mnchen

    Institute for Integrated SystemsChip Multicore Processors

    Tutorial 3

    5

    S. Wallentowitz

    void write(int i) {

    int tmp

    tmp=c;

    while(tmp==N) {

    tmp=c;

    }

    buf[c]=i;

    c=c+1;

    }

    int read() {

    int r, tmp

    tmp = c;

    while(tmp==0) {

    tmp=c;

    }

    r=buf[c];

    c=c-1;

    return r;

    }

  • 8/12/2019 Tutorial04 Solution

    6/21

    Technische Universitt Mnchen

    Institute for Integrated SystemsChip Multicore Processors

    Tutorial 3

    6

    S. Wallentowitz

    void write(int i) {

    int tmp

    tmp=c;

    while(tmp==N) {

    tmp=c;

    }

    buf[c]=i;

    c=c+1;

    }

    int read() {

    int r, tmp

    tmp = c;

    while(tmp==0) {

    tmp=c;

    }

    r=buf[c];

    c=c-1;

    return r;

    }

  • 8/12/2019 Tutorial04 Solution

    7/21

    Technische Universitt Mnchen

    Institute for Integrated SystemsChip Multicore Processors Tutorial 3 7

    S. Wallentowitz

    void write(int i) {

    int tmp

    tmp=c;

    while(tmp==N) {

    tmp=c;

    }

    buf[c]=i;

    c=c+1;

    }

    int read() {

    int r, tmp

    tmp = c;

    while(tmp==N) {

    tmp=c;

    }

    r=buf[c];

    c=c-1;

    return r;

    }

  • 8/12/2019 Tutorial04 Solution

    8/21

    Technische Universitt Mnchen

    Institute for Integrated SystemsChip Multicore Processors Tutorial 3 8S. Wallentowitz

    void write(int i) {

    int tmp

    tmp=c;

    while(tmp==N) {

    tmp=c;

    }

    buf[c]=i;

    c=c+1;

    }

    int read() {

    int r, tmp

    tmp = c;

    while(tmp==N) {

    tmp=c;

    }

    r=buf[c];

    c=c-1;

    return r;

    }

  • 8/12/2019 Tutorial04 Solution

    9/21

    Technische Universitt Mnchen

    Institute for Integrated SystemsChip Multicore Processors Tutorial 3 9S. Wallentowitz

    Condition Variables

    Functions wait()

    signal()or broadcast()

    Wait for condition Append thread to queue of waiting threads

    Suspend thread

    Signal event

    Pop thread from queue

    Re-activate thread

    Broadcast Re-activate all threads in queue

    Thread 0 Thread 1 Thread 2

    wait()

    signal()

    wait()

    signal()

    wait()wait()

    broadcast()

  • 8/12/2019 Tutorial04 Solution

    10/21

    Technische Universitt Mnchen

    Institute for Integrated SystemsChip Multicore Processors Tutorial 3 10S. Wallentowitz

    Condition Variables: Example POSIX Thread

    Wait Wait for a certain condition

    Role of mutex

    Needs to hold mutex

    Blocking call, will still hold mutex after call

    While waiting for the condition: Mutex is released

    Signal Signal to one waiting thread that the condition holds

    Broadcast Signal to all waiting threads that the condition holds

    Useful for example when implementing barriers

    pthread_cond_wait(cond_t*,mutex_t*)

    pthread_cond_signal(cond_t*)

    pthread_cond_broadcast(cond_t*)

  • 8/12/2019 Tutorial04 Solution

    11/21

    Technische Universitt Mnchen

    Institute for Integrated SystemsChip Multicore Processors Tutorial 3 11S. Wallentowitz

    void write(int i) {

    int tmp

    tmp=c;

    buf[c]=i;

    c=c+1;

    }

    int read() {

    int r, tmp

    tmp=c;

    r=buf[c];

    c=c-1;

    return r;

    }

    #define N 100

    int buf[N];int c=0;

    mutex lock;

  • 8/12/2019 Tutorial04 Solution

    12/21

    Technische Universitt Mnchen

    Institute for Integrated SystemsChip Multicore Processors Tutorial 3 12S. Wallentowitz

    Another Example for Conditions: Barrier Implementation

    struct {

    int n_treads;

    int waiting;

    condition complete;

    mutex lock;

    } barr;

    void barrier() {

    mutex_lock(&barr.lock);

    barr.waiting++;

    if (barrier.waiting

  • 8/12/2019 Tutorial04 Solution

    13/21

    Technische Universitt Mnchen

    Institute for Integrated SystemsChip Multicore Processors Tutorial 3 13S. Wallentowitz

    Task 4.1: Counter Implementation

    You want to share a counter among several threads.

    Implement the counter with locks, compare-and-swap and load-linked/store-conditional.

    How is each of the implementations characterized?

  • 8/12/2019 Tutorial04 Solution

    14/21

    Technische Universitt Mnchen

    Institute for Integrated SystemsChip Multicore Processors Tutorial 3 14S. Wallentowitz

    Starting point: Counter

    volatile int count;

    void countup() {

    count++;

    } volatile int count;

    void countup() {

    int tmp;

    tmp = count;

    tmp = tmp+1;

    count = tmp;

    }countup:

    ...

    R3

  • 8/12/2019 Tutorial04 Solution

    15/21

    Technische Universitt Mnchen

    Institute for Integrated SystemsChip Multicore Processors Tutorial 3 15S. Wallentowitz

    Lock Implementation

    volatile int count;

    void countup() {

    int tmp;

    tmp = count;

    tmp = tmp+1;

    count = tmp;

    }

  • 8/12/2019 Tutorial04 Solution

    16/21

    Technische Universitt Mnchen

    Institute for Integrated SystemsChip Multicore Processors Tutorial 3 16S. Wallentowitz

    Compare-and-Swap

    Similar to Test-and-Set

    Test for data value and conditionally replace Read value

    If value matches compared value: swap If value does not match: leave old value

    Return previous value

    Implement non-blocking data structures Threads always progress

    Ad-hoc: For specific algorithm Canned: Provided by libraries

    int cas(int* addr,int compare,

    int swap) {

    int tmp=*addr;

    if (tmp==compare) {

    *addr=swap;

    }

    return tmp;}

    Memory

    (Bus) Interconnect

    data

    ==

    address

    value

    Read

    Modify

    Write

    swap

    compare

  • 8/12/2019 Tutorial04 Solution

    17/21

    Technische Universitt Mnchen

    Institute for Integrated SystemsChip Multicore Processors Tutorial 3 17S. Wallentowitz

    Compare-and-Swap Implementation

    volatile int count;

    void countup() {

    int tmp;

    tmp = count;

    tmp = tmp+1;

    count = tmp;

    }

    int CAS(int* addr,int compare,int swap);

  • 8/12/2019 Tutorial04 Solution

    18/21

    Technische Universitt Mnchen

    Institute for Integrated SystemsChip Multicore Processors Tutorial 3 18S. Wallentowitz

    Load-Linked/Store-Conditional

    Alternative approach: Hardware tracks changes

    Load-Linked (LL): Load value and set linked bit

    Store-Conditional (SC): Store value when data is unchanged

    Returns success of store

    Can also incorrectly fail (implementation dependent):

    Exceptions, other LL, cache line replacement

    Often associated to cache line Requires cache coherency (see module 3)

    Implemented in most architectures PowerPC, ARM, MIPS, ..

    Strictly RISC compared to CAS

    Memory

    (Bus) Interconnect

    data

    Linked

    bit(s)

    write to addr

    reset

    set ==1

    LL

    value addraddr value

    success

    SC

  • 8/12/2019 Tutorial04 Solution

    19/21

    Technische Universitt Mnchen

    Institute for Integrated SystemsChip Multicore Processors Tutorial 3 19S. Wallentowitz

    LL/SC Implementation

    volatile int count;

    void countup() {

    int tmp;

    tmp = count;

    tmp = tmp+1;

    count = tmp;

    }

    int LL(int* addr);

    bool SC(int* addr,int value);

  • 8/12/2019 Tutorial04 Solution

    20/21

    Technische Universitt Mnchen

    Institute for Integrated SystemsChip Multicore Processors Tutorial 3 20S. Wallentowitz

    Task 4.2: FiFo Implementation

    In this task you will implement a FiFo memory in software.

    a) Implement a (capacity bound) FiFo as circular buffer by using an array.

    b) Allow the parallel access to the FiFo by multiple threads using locks.

    c) Is it possible to use two locks for parallel access by reading and writing threads?

    d) Use a (POSIX) condition variable for synchronization.

    e) Can you implement this data structure in a non-blocking fashion? If not, how can you

    change the data structure to allow for it?

    f) Is it possible to implement an (unbounded) FiFo by using a linked list and without

    locking?

  • 8/12/2019 Tutorial04 Solution

    21/21

    Technische Universitt Mnchen

    Institute for Integrated SystemsChip Multicore Processors Tutorial 3 21S Wallentowitz

    FiFo Implementation

    int data[N];

    unsigned int start;

    unsigned int end;

    void enqueue(int d) {

    while(((end+1)%N)==start)) {}

    data[end] = d;end = (end+1)%N;

    }

    int dequeue() {

    int d;

    while(end==start) {}

    d=data[start];

    start=(start+1)%N;

    return d;

    }