Concurrency

Document Sample
Concurrency Powered By Docstoc
					Concurrency
    Levels of concurrency

   Instruction       machine
   Statement         programming language
   Unit/subprogram   programming language
   Program           machine, operating system
Kinds of concurrency
 Co-routines – multiple execution
  sequences but only one executing at
  once
 Physical concurrency – separate
  instruction sequences executing at
  the same time
 Logical concurrency – time-shared
  simulation of physical
     Subprogram call compared to
     unit level concurrency
     Procedure call     Task invocation
     (sequential)       (concurrent)
      B                   B




    call A      A       invoke A   start A
(B suspended)

  resume B      end A
Synchronization of concurrent tasks
Disjoint            Cooperative              Competitive

A    B               A    B              A          B          C

                                                (block)
                                                          (block)
                (block)




           e.g., copy between media     e.g., updating elements of
           of different access speeds   a data set
   A competitive synchronization
   problem example
 Modify a bank account: balance $200
 Transaction task A – deposit $100        Task should have
                                          exclusive access
 Transaction task B – withdraw $50

Sequence I:               Sequence II:         Sequence III:
A fetch 200               A fetch 200          B fetch 200
A add 100 (to copy)       B fetch 200          B subtract 50
A store 300               A add 100            B store 150
B fetch 300               A store 300          A fetch 150
B subtract 50 (fr copy)   B subtract 50        A add 100
B store 250               B store 150          A store 250
(Task) Scheduler
 Allocates tasks to processor(s) for a
  period of time ‘time slice’
   Tracks which tasks are ready to run
    (e.g., not blocked)
   Maintains priority queue of ready tasks
   Allocates next task when a processor is
    free
Concurrency control structures
 Create, start, stop, destroy tasks
 Provide mutually exclusive access to shared
  resources (e.g. bank account)
 Make competing and cooperating tasks wait
  (for shared resource or other action)
 Three models
  1. Semaphores
  2. Monitors
  3. Message passing
Scheduler
 States a task can be in:
                                     deadlock
                 blocked             danger




  new       runnable       running              dead
1. semaphore model
 semaphore data structure
   queue of waiting processes
   counter of available resources
 ideal for cooperative synchronization
   eg reading and writing from a buffer
    reader must wait if buffer is empty
    writer must wait if buffer is full
 also for competitive synchronization
 semaphores
 control statements “guard” parts of code that
  depend on synchronization with other tasks:
   wait(s)              // s is a semaphore
   release(s)
  e.g. competition for shared resource ‘account’

       semaphore accountAccess
       task doDeposit
         loop
           get(amount)
           wait(accountAccess)
           deposit(amount, account)
           release(accountAccess)
         end loop
 concurrent processes
 semaphore accountAccess
 task doDeposit
                               wait(s)
 loop
                                              wait(s)
    get(amount)
    wait(accountAccess)        deposit
    deposit(amount, account)
                               release(s)
    release(accountAccess)
 end loop
                                             deposit
deposit includes:
                                            release(s)
fetch, add and store
 semaphores
e.g. cooperative synchronization by producer and
consumer sharing buffer (queue)
semaphore queueNotFull, queueNotEmpty

task produce            task consume
loop                    loop
 getTransaction(amount) wait(queueNotEmpty)
 wait(queueNotFull)      getQueue(amount)
 putQueue(amount)        release(queueNotFull)
 release(queueNotEmpty) doTransaction(amount)
end loop                end loop
   complete processes
semaphore accountAccess, queueAccess,
  queueNotFull, queueNotEmpty

task produce            task consumeAndDoDep
loop                    loop
 getTransaction(amount) wait(queueNotEmpty)
                         wait(queueAccess)
 wait(queueNotFull)
                         getQueue(amount)
 wait(queueAccess)
                         release(queueNotFull)
 putQueue(amount)        release(queueAccess)
 release(queueNotEmpty) wait(accountAccess)
 release(queueAccess)    deposit(amount,account)
end loop                 release(accountAccess)
                        end loop
semaphore implementation
 counter + queue of waiting tasks
                                       wait(queueNotFull)
queueNotFull
                       count*   5      // count--, proceed

                       queue           release(queueNotFull)
                                       // count++

                                         wait(queueNotFull)
queueNotFull
                       count    0        // blocked, join queue
                       queue             release(queueNotFull)
                                         //unblock first on queue



   * available space in buffer of transaction queue
semaphore problems
 semaphore is a data structure -> need
  exclusive access to it too!
   must be implemented with ‘uninterruptible’
    instruction set
 vulnerable to deadlock – omitted ‘release’
 vulnerable to data corruption or run time
  error – omitted ‘wait’
 can’t check statically for correct control –
  e.g., different units
2. monitors
 The (Concurrent)Pascal / Modula model of
  concurrency – late 70’s
 keywords
    concurrent tasks:            process, init
    data resource shared:        monitor, entry, queue
 competitive synchronization strategy:
    create a monitor to contain all data with shared access
     and write procedures for accessing; monitor implicitly
     controls competitive access
    write process tasks using the monitor procedures
 monitor is essentially an object
  monitor example:
  competitive synchronization
type account =                type acctMgr =
 monitor                       process(acct: account);
  var bal: real;                var amt: real;
  procedure entry deposit           request: integer;
           (dep: integer);      begin
  begin                          cycle
   bal := bal + dep               <<get request, amt>>
  end;                            if request = 0
  procedure entry withdraw         then
             (wd: integer);         acct.deposit(amt);
  begin                            else
   bal := bal - wd                  acct.withdraw(amt);
                                 end
  end;
                                end;
 begin
  bal := 0.0
 end;
monitor example:
competitive synchronization
<< following the type declarations >>
var bankAcct account;
     mgr1, mgr2, mgr3: acctMgr;
begin
  init bankAcct,
        mgr1(bankAcct),
        mgr1(bankAcct),
        mgr1(bankAcct);
end;
 monitors and
 cooperative synchronization
 type queue: semaphore-like object used
  inside a monitor
 two procedures: delay and continue
   similar to wait and release
  BUT
   delay always blocks process (task) so
    programmer of monitor must control its use
   delay and continue override monitor access
    control
 monitor example:
 cooperative synchronization

producer: process(buffer)                       consumer: process(buffer)



 buffer.deposit()        new_buffer:databuf          buffer.fetch()

                            buf: array
                                         …
                    procedure            procedure
                     deposit               fetch

                            sender_q: queue
                                         …
                            receiver_q: queue
                                         …
monitor problems
 central data structure model is not
  appropriate for distributed systems, a
  common environment for concurrency
 terminating processes occurs at end
  of program only
 3. synchronous message passing
 message sent from one sender task to
  another receiver task and returned
 message may have parameters – value,
  result or value-result
 message is sent when tasks synchronize
  (both blocked and need the message to
  continue)
 time between send and return is rendezvous
  (sender task is suspended)
   concurrency with messages
    sender          receiver           sender      receiver

message statement                                 receive message

  blocked                                                blocked
                 receive message     message statement

suspended                          suspended




    rendezvous
example 1: receiver task structure
(Ada83)     specification
             task acct_access is
              entry deposit (dep : in integer);
             end acct_access;
 body
task body acct_access is
 balance, count : integer;
 begin
 loop
  accept deposit(dep : in integer) do
    balance := balance + dep;
  end deposit;
  count := count + 1;
 end loop;
end acct_access;
extended example 2: receiver task
 body                        specification
task body acct_access is     task type acct_access is
 balance, count : integer;     entry deposit (dep : in integer);
 begin
                               entry getBal(bal : out integer);
 balance := 0;
                             end;
 count := 0;
 loop
  select
   accept deposit (dep : in integer) do
     balance := balance + dep;
   end deposit;
  or
   accept getBal (wd : out integer) do
     bal := balance;
   end getBal;
  end select;
  count := count + 1;
 end loop;
end acct_access;
important points
 receiver is only ready to receive a message
  when execution comes to an ‘accept’ clause
 sender is suspended until accept ‘do..end’
  is completed
 select is a guarded command – eligible
  cases selected at random
 tasks can be both senders and receivers
 pure receivers are ‘servers’
 pure senders are ‘actors’
message example: (Sebesta, p.578-9)
cooperative/competitive synchronization

 PRODUCER TASK                                CONSUMER TASK

  loop                                          loop
   produce k           BUF_TASK TASK             buffer.fetch(k)
   buffer.deposit(k)                             consume k
  end loop                                      end loop
                        BUF: array
                                     …

                       loop
                        select
                         guarded deposit(k)
                        or
                         guarded fetch(k)
                        end select
                       end loop
messages to protected objects
 tasks to protect shared data are slow
  (rendezvous are slow)
 protected objects are a simpler,
  efficient version
 similar to monitors
 distinction of write access (exclusive)
  and read access (shared)
(SEE ALSO Binary Semaphores, p.580)
asynchronous messages
 no rendezvous
   the sender does not block after sending
    message (therefore, does not know it
    has been executed)
   the receiver does not block if a message
    is not there to be received (continues to
    some other processing)
   asynchronous messages
   sender       receiver            sender         receiver

message statement                                 receive message
           queued                                 (no message)

               receive message
                       execute
                       message     message statement
                       procedure
                                         queued
  Ada’s (95) asynchronous ‘select’


   select            or      then abort

                   delay k
‘accept’ message
related features of Ada (p.580)
 binary semaphores built as tasks to protect
  data access (pseudocode)
task sem is
 entry wait;              <in user task>
 entry release;           aSem : sem;
end sem;                  aSem();
task body sem             ...
 begin                    aSem.wait();
  loop                    point.x = xi;
   accept wait;           aSem.release();
   accept release;        ...
  end loop;
end sem;
Java concurrency: Threads
 classes and interfaces
     Thread, Runnable
     ThreadGroup
     ThreadDeath //deprecated
     Timer, TimerTask
     Object
creating a thread
 extend Thread class
  NewThread extends Thread {}
  NewThread n = new NewThread();
  n.start();
 implement a Runnable interface
  NewT implements Runnable {}
  NewT rn = new NewT()
  Thread t = new Thread(rn);
  t.start();
terminating a thread
 stop();     //deprecated
   throws a ThreadDeath object
 set thread reference to null
thread states

                                wait()

                  running       notify[All]()
      scheduler
                      yield()   IO block
                                unblock
                                            not runnable
new             runnable        sleep(.)
      start()
                                times out
                    terminate
                                join(t)

                  dead          waits for
                                t to die
priorities
 Thread class constants, methods for
  managing priorities
     setPriority, getPriority
     MAX_PRIORITY, MIN_PRIORITY,
      NORM_PRIORITY
 Timeslicing is not defined in the java
  runtime scheduler*; interrupts for
  higher priority only
     yield(): suspend and go to ‘runnable’


*timeslicing is typically round-robin among highest priority tasks
competitive synchronization
 synchronized keyword for methods
  or block of code – associates a lock
  with access to a resource, p.586
 object acts like a monitor
 re-entrant locks
   one synchronized method can call
    another without deadlock
cooperative synchronization
 wait() and notify(), notifyAll()
   in Object class
   like delay and continue, wait and release
 example code from java.sun.com
  tutorial
Scheduling tasks
 Timer and TimerTask
 Timer is a special thread
   for scheduling tasks at some future time
   use daemon threads for regular threads
    that should not prevent the ending of a
    program
thread groups
 all threads belong to groups
 default group is main
 threadgroups form a hierarchy (like a
  directory structure)
 access control (e.g. security) is by
  management of thread groups
statement level concurrency
 concurrent execution with minimal
  communication
 useless without multiple processors
 SIMD (Single Instruction Multiple
  Data)
   simpler, more restricted
 MIMD (Multiple Instruction Multiple
  Data)
   complex, more powerful
 e.g. array of points – find closest to
 origin
public int closest(Point[] p)
{
 double minDist=Double.MAX_VALUE;
 int idx;
 for (int i=0; i<p.length; i++)
 {
   double dist = p[i].distance();// independent
   if (dist<minDist) idx = i; // synchronized
 }
 return idx;
}
 e.g. array of points – find closest to
 origin – SIMD concurrent execution
public int closest(Point[] p)
{
 double minDist=Double.MAX_VALUE;
 int idx;
 double[] dist = new double[p.length];
 forall (int i=0:p.length) // pseudo-code
   dist[i] = p[i].distance();
 for (int i=0; i<p.length; i++)
  if (dist[i]<minDist) idx = i;
 return idx;
}
sequential vs concurrent
                           i = 0,1,...,n-1

 i=0



 i<n   i++          i=0



                    i<n        i++
high performance Fortran HPF
 concurrency
   FORALL – process elements in lockstep
    parallel
   INDEPENDENT –iterated statements can
    be run in any order
 distribution to processors
   DISTRIBUTE – pattern for allocating
    array elements to processors
   ALIGN – matching allocation of arrays
    with eachother
FORALL: note synchronization
FORALL ( I = 2 : 4 )
 A(I) = A(I-1) + A(I+1)
 C(I) = B(I) * A(I+1)
END FORALL
get all A[I-1], A[I+1], calc sums
assign sums to all A[I]
get all B[I], A[I+1], calc products
assign products to all A[I]
INDEPENDENT compiler directive
!HPF$ INDEPENDENT
DO J = 1, 3
 A(J) = A( B(J) )
 C(J) = A(J) * B(A(J))
END DO
declares iterations independent and OK
  to execute in parallel
DISTRIBUTE


 2 DIMENSIONAL
 ARRAYS
 ON 4 SIMD
 PROCESSORS
 (colours)


                    http://www.cs.rice.edu/~chk/hpf-prose.html

!HPF$ DISTRIBUTE A(BLOCK,*)
                    !HPF$ DISTRIBUTE B(*,CYCLIC)
!HPF$ DISTRIBUTE C(BLOCK,BLOCK)
        !HPF$ DISTRIBUTE D(CYCLIC(2),CYCLIC(3)
ALIGN – put corresponding
elements on same processor

!HPF$ ALIGN X(I,J) WITH W(J,I)
!HPF$ ALIGN Y(K) WITH W(K,*)
  X           W           Y

				
DOCUMENT INFO
Shared By:
Categories:
Tags:
Stats:
views:0
posted:5/11/2013
language:Unknown
pages:51