Communication Spaces ==================== "The world consists of rooms for communication" Processes plus spaces within which processes may interact - not shared memory: interaction controlled by space interface - not message passing: not direct interaction with other processes similar: channels->mailboxes Monitors ======== Already described in shared memory section - Modules protecting ADTs for concurrent access - implicit lock on access functions - condition variables, WAIT() and SIGNAL() Shared Data Abstractions (SDAs) =============================== Opus language (University of Vienna) - generalization of HPF - integrating task and data parallelism - data parallel parts DP_i in HPF - combination of various DP_i by Opus SLIDE Chapman et al, Fig 2, p. 673 Tasks ----- TASK CODE p(...) .... END TASK CODE T1 = SPAWN p(x, y, z) [ON MACHINE('iPSC860')] T2 = SPAWN q(...) [ON(T2) PROCESSORS(NEW 32)] ... WAIT CHILDREN SDA TYPE declaration -------------------- Parameterized class declaration SDA TYPE stack(max) OF (T) INTEGER max TYPE(T), PRIVATE :: lifo(MAX) INTEGER, PRIVATE count ... CONTAINS SUBROUTINE get(x) WHEN(count.gt.0) TYPE(T) x x = lifo(count) count = count-1 END ... END SDA Similar to Monitors - General WAIT() conditions evaluated every time when task exits SDA SDA Variables ------------- Object declaration SDA (stack) OF INTEGER :: int_stack SDA (stack) OF TYPE(user_type) :: user_stack Initialization CALL int_stack%INIT(100) CALL user_stack%INIT(1000) Method invokation CALL int_stack%get(X) Saving and restoring CALL int_stack%LOAD('stack_sav') CALL int_stack%SAVE('stack_sav') Arbitrary many SDA instances can be generated - (almost) normal objects, can be passed to subroutines/tasks SLIDE Figure 3-5 CC++ ==== Compositional C++, CalTech 1992 Parallel Block -------------- par { stat_1; ...; stat_n } parfor(i = 0; i < n; i++) { stat; } synchronous parallelism Spawns ------ { stat_1; spawn f(x) stat_2; } Asynchronous parallelism Atomicity --------- atomic void f(int x); Execution of f is *atomic* action, no other operation must occur between Sync Type --------- sync T x Single assignment data type - initially *empty* - any access to *empty* sync object blocks task - may be assigned value at most once - assignment releases blocked task (-> idea from dataflow/functional programming, see later) Logical Processor Objects ------------------------- global class worker { public: int do_work(task); int status; } worker *wPtr = new(Node) worker("~carl/worker") - creates new processor object on particular node - initialization with executable in particular file wPtr->status++ wPtr->do_work(task(23)) Possible to access members/call methods of remote process objects - message passing hidden below Facility to start remote activities and interact with them Logical Processor Object + sync vars + atomic functions similar to Monitor/SDA Global Pointers --------------- int *global g_ptr; *global* pointer to integer - may be passed to logical processor objects - *network-wide* access to objects - global pointer = (processor id, local pointer) Possibility to build distributed data structures Programming Examples -------------------- "Dataflow program" SLIDE Chandy et al, Figures 1 and 2 "Parafunctional program" SLIDE Chandy et al, pages 34 "Distributed Abstract Datatypes" SLIDE Chandy et al, page 35 "Monitors" SLIDE Chandy et al, page 36 Combination ----------- - Object-oriented (see later) - SDAs, Monitors - RPCS (r = worker->f(x)) - Message Passing (worker->send(x), r = worker->receive()) - Shared memory (global pointers) - Functional, dataflow (sync vars)