Sunteți pe pagina 1din 58

Aplicaii ale

paralelismului de date
Ciprian Dobre
ciprian.dobre@cs.pub.ro

Programarea concurent n
Java

Procese i fire de execuie

Partajare date n Java


Fire de execuie
Proces
Instan a unui program n
execuie
Pentru un proces, SO
aloc:
Un spaiu n memorie
(codul programului,
zona de date, stiva)
Controlul anumitor
resurse (fiiere,
dispozitive I/O, )

Process1

Process2

Process
Process
Control
Control Block
Block

Process
Control Block

Code
Code

Code
Code

Data
Data

Data
Data

Stack
Stack

Stack
Stack

Fire de execuie

Un proces poate avea mai


multe fire de execuie
Fir de execuie (thread):
Flux de control secvenial n
cadrul unui proces

Firele de execuie
mpart acelai spaiu de
adrese;
au n comun: zonele de cod i
date din memorie, resursele
procesului
zona de stiv reprezint
starea curent a thread-ului i
este proprie thread-ului

Process
Process
Control
Control Block
Block
Code
Code

Data
Data

Thread1

Thread2

Thread
Control Block

Thread
Control Block

Stack

Stack

Multi-proces vs. multi-thread

Process1

Process2

Process
Process
Control
Control Block
Block

Process
Control Block

Code
Code

Process
Process
Control
Control Block
Block
Code
Code

Data
Data

Code
Code

Thread1

Thread2

Data
Data

Data
Data

Thread
Control Block

Thread
Control Block

Stack
Stack

Stack
Stack

Stack

Stack

Execuia thread-urilor

P1
P2

Thread1

Sisteme multiprocesor:

Thread2

execuie n paralel

Sisteme uniprocesor:

planificarea este
t

realizat de ctre
sistemul de operare

politici: divizarea
timpului (time sharing),
prioriti

Avantaje ale utilizrii firelor de execuie

mbuntirea productivitii
n sistemelor multiprocesor: utilizarea simultan a
procesoarelor
n general: utilizarea simultan a diverselor resurse

Ex: n timp ce se ateapt la un dispozitiv I/O, se pot executa alte


operaii cu procesorul

mbuntirea timpului de rspuns al interfeelor


grafice
Avantaj fa de procese: crearea unui nou fir de
execuie este mai ieftin
Structurarea mai bun a programelor mai multe
uniti de execuie

Programare concurent n Java

Limbajul ofer suport pentru fire de execuie


Avantaj: programarea este independent de
platform
ncepnd cu versiunea 1.5: set variat de clase
utilitare pentru programarea concurent
Pentru crearea firelor de execuie:
Clasa java.lang.Thread
Interfaa Runnable

Metode specifice clasei Thread:


start(), sleep(), getPrority(), setPriority()

Metode specifice clasei Object:


wait(), notify()

Exemplu: Crearea unui fir de execuie

Controlul execuiei thread-urilor

De ctre JVM:
Prin intermediul prioritilor: ntre Thread.MIN_PRIORITY
(1) i Thread.MAX_PRIORITY(10)

De ctre sistemul de operare:


Fr divizarea timpului: thread-ul cedeaz controlul prin
metode ca yield() sau wait()
Se poate ntampla ca un thread s preia controlul i s
se execute fr ntrerupere, mpiedicnd execuia
altora
Cu divizarea timpului: fiecare thread se execut pentru o
cuant de timp, apoi se trece la execuia altuia etc.

Strile posibile ale unui thread

Creat: obiectul a fost creat cu operaia


new(); se poate apela metoda start()
Gata de execuie: a fost apelat metoda
start(), firul poate fi executat
Suspendat: a fost apelat sleep() sau
wait()
Terminat: metoda run() a fost terminat

Exemplu: Programare concurent

Scenariu:
instaniemunobiectxde
tipulTestMem
pornimdoufirede
execuie
ntrunfirdeexecuie
apelmx.modific(),
iarncellaltapelm
x.afieaz()
ntrebare:
Putemtiexactcesevaafia
peecran?

Exemplu

Scenariu de execuie

Rezultat
GATA main!
2 a = 0 b =
1 a = 0 b =
1 a = 2 b =
2 a = 3 b =
1 a = 4 b =
2 a = 5 b =
GATA!
GATA!

0
0
1
2
3
4

Sincronizarea firelor de execuie

Dou situaii:
Concuren
Cooperare
Sincronizarea
asigur excluderea mutual un singur fir poate executa la un
moment dat o metod (secven de cod) sincronizat: seciune
critic
Folosete mecanismul de zvor :

Fiecare obiect are asociat cte un zvor


synchronized(o) asigur intrarea n seciunea critic
se poate asocia unei metode sau unei secvene de cod
pe parcursul execuiei secvenelor de cod sincronizate, zvorul este
nchis

Exemplu: Sincronizare pentru accesul


concurent la o resurs (1)

Exemplu: Sincronizare pentru accesul


concurent la o resurs (2)

Exemplu: sincronizare cu zvoare

Metode:
synchronized:
lock pe obiect
static synchronized:
lock pe clas

Exemplul 2 (lazy instantiation)


Class Singleton {
private static Singleton uniqueInstance = null;
private Singleton( ) { .. } // private constructor
public static Singleton getInstance( ) {
if (uniqueInstance == null)
uniqueInstance = new Singleton();
// call constructor
return uniqueInstance;
}
}
19
Instrumente pentru dezvoltarea programelor Curs 7

Singleton: Double check locking

20

Singleton: Double check locking


Cnd avem mai multe thread-uri, avem nevoie
de synchronized:

De fiecare dat cnd apelm ns metoda


apare un overhead suplimentar
n realitate ns nu avem nevoie s form
dect verificarea la:
Modul acesta de verificare se numete Double
check locking

Singleton: Double check locking

sau.

Metoda wait()

Permite manevrarea zvorului asociat cu un obiect


La apelul metodei wait() pentru un obiect m de
ctre un fir de execuie t:
se deblocheaz zvorul asociat cu m i t este
adugat la un set de thread-uri blocate, wait set-ul
lui m
dac t nu deine zvorul pentru m:
IllegalMonitorStateException
t va continua execuia doar cnd va fi scos din wait
set-ul lui m, prin:
o operaie notify() / notifyAll()
expirarea timpului de ateptare

Notificri

Metode: notify(), notifyAll()


La o notificare apelat din thread-ul t pentru
obiectul m:
notify(): un thread u din wait set-ul lui m este
scos i repus n execuie
notifyAll(): toate thread-urile sunt scoase
din wait set-ul lui m dar numai unul va
putea obine zvorul
daca t nu deine zvorul pentru m:
IllegalMonitorStateException

Exemplu sincronizare pentru


colaborare (1)

Exemplu sincronizare pentru


colaborare (2)

Exemplu sincronizare pentru


colaborare (3)

Suportul pentru concuren n JDK 5.0


Pachet nou: java.util.concurrent
mbuntiri:
Schimbri la nivelul mainii virtuale:
exploatarea noilor instruciuni disponibile la
procesoarele moderne
Clase utilitare de baz:
Lock-uri
Variabile atomice

Clase de nivel nalt:


Semafoare
Bariere
Pool-uri de fire de execuie

Clase utile pentru sincronizare n JDK 1.5


Semaphore
Mutex
CyclicBarrier
barier reutilizabil
are ca argument un contor care arat numrul
de fire din grup
CountDownLatch
similar cu bariera, are un contor, dar
decrementarea contorului este separat de
ateptarea ajungerii la zero
decrementarea semnific terminarea unor
operaii
Exchanger
rendez-vous cu schimb de valori n ambele

Faciliti pentru sincronizare de nivel


sczut
Lock
generalizare lock monitor cu ateptri
contorizate, ntreruptibile, teste etc.
ReentrantLock
Conditions
permit mai multe condiii per lock
ReadWriteLock
exploatarea faptului c, la un moment dat, un
singur fir modific datele comune i ceilali
doar citesc
Variabile atomice:
AtomicInteger
AtomicLong
AtomicReference

Exemplu: Utilizare semafoare in Java 1.5

Referine

[Ath02] Irina Athanasiu

Java ca limbaj pentru programarea distribuit, MatrixRom,


2002
[JLS05] - The Java Language Specification
http://java.sun.com/docs/books/jls/
[J2SE05N] - J2SE 5.0 in a Nutshell
http://java.sun.com/developer/technicalArticles/release
s/j2se15/
Threads: Basic Theory and Libraries
http://www.cs.cf.ac.uk/Dave/C/node29.html

Aplicaii ale
paralelismului de date

Paralelism de date

Procesoarele ruleaz simultan


aceleai taskuri asupra unui set
distribuit de date
Embarrassingly parallel
Aplicaii:
Vectori
Matrice
Liste

Aplicaii folosind paralelismul de date


Calculul sumelor prefix
Problem:

Se d tabloul a[1:n], se cere s[1:n], unde:

Algoritm secvenial:
s[1] := a[1];
fa i := 2 to n ->
s[i] := a[i] + s[i-1]
af

Algoritm paralel:
- derivat din algoritmul sumei elementelor unui vector

Suma elementelor unui vector

procesoarepai

Suma elementelor unui vector

a2

a3

a4

a5

a6

a7

a8

a1

a3

a5

a7

a1

a3

a5

a7

a1

a3

a5

a7

Timp

a1

Suma elementelor unui vector

a5

a6

a7

a8

a1

a3

a5

a7

a1

a3

a5

a7

a1

a3

a5

a7

Timp

var
a: array [1:n] of int;
co suma
(k:1..n)::
fa j := 1 to sup() ->
if k mod 2j = 0 ->
a[k] := a[k-2j-1] + a[k]
fi
barrier
af
a1
a2
a3
a4
oc

Sume prefix (varianta 1)

a2

a3

a4

a5

a6

Timp

a1

Sume prefix varianta 1

var
a: array [1:n] of int;
co suma(k:1..n)::
fa j := 1 to sup() ->
if k - 2j-1 >= 1 ->
a[k] := a[k-2j-1] + a[k]
a
a
a
fi
barrier
af

oc
1

Eroare de sincronizare

a4

a5

a6

Sume prefix varianta 1 probleme

Presupunem c procesorul numrul 3 este mai lent dect


restul.
Suprascriere a locaiei de memorie
a1

a2

a3

a4

a5

a6

Sume prefix varianta 2

var a, temp: array [1:n] of int;


co suma(k:1..n)::
fa j := 1 to sup(log2 n) ->
temp[k] := a[k];
barrier
if k - 2j-1 >= 1 ->
a[k] := temp[k-2j-1] + a[k]
fi
barrier
a1
af
oc

a2

a3

Sume prefix varianta 3

var a, temp: array [1:n] of int;


co suma(k:1..n)::
var d := 1;
do d < n ->
temp[k] := a[k];
barrier
if k d >= 1 -> a[k] := temp[k-d] + a[k]
fi
barrier
d := 2 * d
od
oc

Notaie SIMD
do steps i to j in parallel
step i
...
step j
od
fa i := j to k do in parallel
operaiile lui Pi
af
fa i := r, s, ...t do in paralel
operaiile lui Pi
af
fa i in S do in paralel
operaiile lui Pi
af

Sume prefix varianta 1 SIMD

var a: array [1:n] of int;


fa k := 1 to n do in parallel
(Procesor Pk)
var temp: int; /* local Pk */
var d := 1;
do d < n ->
if k d >= 1 -> temp := a[k-d];
a[k] := temp + a[k]
fi
d := 2 * d
od
af

Sume prefix varianta 1 SIMD

Se observ c, la anumii pai, unele procesoare nu


opereaz.
a1

a2

a3

a4

a5

a6

Pas 1: P1

Pas 2: P1,
P2

Pas 3: P1, P2, P3, P4

Sume prefix varianta 2 SIMD

Varianta pune n eviden procesoarele care


lucreaz.

var A: array [1:N] of real;


fa j := 0 to log N - 1 do
fa k := 2j+1 to N do in parallel
(Procesor Pk)
var temp: real;
/* temp locala procesorului k */
1. temp := A[k-2j];
2. A[k] := temp + A[k]
af
af

Operaii cu vectori broadcast

Pas 1: (Procesorul P1)


var t: real;/* t locala P1 */
t := D;
A[1] := t;
Pas 2:
fa i = 0 to (log N -1) do
fa j = 2i+1 to 2i+1 do in parallel
/* (Procesor Pj) */
var t: real; /* t local Pj */
t := A[j-2i]
A[j] := t;
af
af

Operaii cu vectori broadcast

Ex: dorim s propagm valoarea 15 la toate


procesoarele.

15

15

15

15

15

15

15

15

Operaii cu matrice - produs

var a, b, c: array [1:n, 1:n] of


real;
co Prod(i:1..n, j:1..n)::
var sum : real := 0;
fa k := 1 to n ->
sum := sum + a[i,k] * b[k,j]
af
c[i,j] := sum
oc

Operaii cu matrice - gril

Soluie
n dou dimensiuni pentru Laplace:

Grila [0:n+1, 0:n+1]: matrice de puncte


Diferene finite: la fiecare iteraie un punct
interior ca media aritmetic a vecinilor
Metoda staionar: soluia converge cnd
noile valori difer de vechile printr-un

Operaii cu matrice - gril

var grila, noua: array [0:n+1, 0:n+1] of


real;
var converge: boolean := false;
co CalculGril(i:1..n, j:1..n)::
do not converge ->
noua[i,j] := (grila[i-1,j]+
grila[i+1,j]+
grila[i,j-1]+
grila[i,j+1])/4;
barrier
test_convergen;
barrier
gril[i,j] := nou[i,j];
barrier
od
oc

Operaii cu liste

List n elemente: data[1:n]


Legturile ntre elemente: leg[1:n]
Capul listei: cap
Elementul i face parte din list fie
cap = i
exist un element j, ntre 1 i n, a.. leg[j]=i
cap

Date

Date

Date

Date

Date

Problem: vrem ca fiecare procesor s afle

Operaii cu liste

var leg, end: array [1:n] of int;


co Afl (i:1..n)::
var nou: int; d:int:=1;
end[i] := leg[i];
barrier
do d<n ->
nou := 0;
if end[i]<>0 and end[end[i]]<>0 ->
nou:=end[end[i]] fi
barrier
if nou<>0 -> end[i]:=nou fi
barrier
d := 2*d
od
oc

Operaii cu liste

cap

Date

Date

Date

Date

Date

Procesor

End[i]

End[i]

End[i]

End[i]

d=1
d<5

d=2
d<5

d=4
d<5

init

var leg, end: array [1:n] of int;


co Afl (i:1..n)::
var nou: int; d:int:=1;
end[i] := leg[i];
barrier
do d < n ->
nou := 0;
if end[i]<>0 and end[end[i]]<>0 ->
nou := end[end[i]]
fi
barrier
if nou <> 0 ->
end[i] := nou
fi
barrier
d := 2 * d
od
oc

Varianta SIMD

var leg, end: array [1:n] of int;


fa i:=1 to n do in paralllel
end[i] := leg[i];
do end[i] <> 0 and end[end[i]] <> 0 ->
end[i] := end[end[i]];
od
af

Sumar

Suportul pentru concuren n Java


Aplicaii ale paralelismului de date
Sume prefix
Notaii SIMD
Operaii cu liste

ntrebri?

S-ar putea să vă placă și