02 - Pthread+primitive Sincronizare PDF

Download as pdf or txt
Download as pdf or txt
You are on page 1of 169

Arhitecturi Paralele

Pthread + Primitive sincronizare


Prof. Florin Pop
As. Drd. Ing. Cristian Chilipirea
[email protected]

Elemente preluate din cursul Prof. Ciprian Dobre


Types of parallelism
▪ Bit level

▪ Instruction level

▪ Task parallelism

Florin Pop – Cristian Chilipirea


Types of parallelism
▪ Bit level
oC=A&B
▪ Instruction level

▪ Task parallelism

Florin Pop – Cristian Chilipirea


Types of parallelism
▪ Bit level

▪ Instruction level 9 6 9 C=A+B

▪ Task parallelism
4 2 7

Adunarea a doi vectori

Florin Pop – Cristian Chilipirea


Types of parallelism
▪ Bit level

▪ Instruction level

▪ Task parallelism

‒ Multi-Tasking (pot comunica și procesele)


‒ Multi-Threading

Florin Pop – Cristian Chilipirea


Types of parallelism
▪ Bit level

▪ Instruction level

▪ Task parallelism

‒ Multi-Tasking (pot comunica și procesele)


‒ Multi-Threading
Cum pot comunica două procese?

Florin Pop – Cristian Chilipirea


Notații pseudocod

co S1 || S2 || ... || Sn oc
Ex.1:
x=0; y=0;
co x=x+1 || y=y+1 oc
z=x+y;

Florin Pop – Cristian Chilipirea


Notații pseudocod

co [cuantificator]{Sj}
Ex. 2:
co [j=1 to n] {a[j]=0; b[j]=0;}

Florin Pop – Cristian Chilipirea


POSIX threads
pthread_t thread;
pthread_create(&thread, NULL, threadFunction, arg);

void * threadFunction(void* arg)


{

pthread_join(thread, NULL);

Florin Pop – Cristian Chilipirea


Compilare pthread

gcc –o executabil cod.c –lpthread –lrt

#include<pthread.h>
#include<semaphore.h>

Florin Pop – Cristian Chilipirea


Pthread
pthread_t thread;
pthread_create(&thread, NULL, threadFunction, arg);

void * threadFunction(void* arg)


{

Acest element reprezintă thread-ul.


} Poate fi considerat handle

pthread_join(thread, NULL);

Florin Pop – Cristian Chilipirea


Pthread
pthread_t thread;
pthread_create(&thread, NULL, threadFunction, arg);

void * threadFunction(void* arg)


{
Aici am putea să facem recomandări
sistemului de operare. Gen să
} folosească anumite core-uri.

pthread_join(thread, NULL);

Florin Pop – Cristian Chilipirea


Pthread
pthread_t thread;
pthread_create(&thread, NULL, threadFunction, arg);

void * threadFunction(void* arg)


{
Când se crează thread-ul, acesta va
} începe la această funcție.

pthread_join(thread, NULL);

Florin Pop – Cristian Chilipirea


Pthread
pthread_t thread;
pthread_create(&thread, NULL, threadFunction, arg);

void * threadFunction(void* arg)


{
Așa trimitem date thread-ului
}

pthread_join(thread, NULL);

Florin Pop – Cristian Chilipirea


Pthread
pthread_t thread;
pthread_create(&thread, NULL, threadFunction, arg);

void * threadFunction(void* arg)


{
Astfel se pot extrage
} informații din thread

pthread_join(thread, NULL);

Florin Pop – Cristian Chilipirea


Florin Pop – Cristian Chilipirea
Pthread

int main(int argc, char **argv)


{
int i, P=2;
pthread_t tid[P];
for(i = 0; i < P; i++) {
pthread_create(&(tid[i]), NULL, threadFunction, NULL);
}
for(i = 0; i < P; i++) {
pthread_join(tid[i], NULL);
}
return 0;
}

Florin Pop – Cristian Chilipirea


Pthread

int main(int argc, char **argv)


{
int i, P=2;
pthread_t tid[P];
for(i = 0; i < P; i++) {
pthread_create(&(tid[i]), NULL, threadFunction, NULL);
}
for(i = 0; i < P; i++) {
pthread_join(tid[i], NULL);
}
return 0;
}

Florin Pop – Cristian Chilipirea


Pthread

int main(int argc, char **argv)


{
int i, P=2;
pthread_t tid[P];
for(i = 0; i < P; i++) {
pthread_create(&(tid[i]), NULL, threadFunction, NULL);
}
for(i = 0; i < P; i++) {
pthread_join(tid[i], NULL);
}
return 0;
}

Florin Pop – Cristian Chilipirea


Pthread

int main(int argc, char **argv)


{
int i, P=2;
pthread_t tid[P];
for(i = 0; i < P; i++) {
pthread_create(&(tid[i]), NULL, threadFunction, NULL);
}
for(i = 0; i < P; i++) {
pthread_join(tid[i], NULL);
}
return 0;
}

Florin Pop – Cristian Chilipirea


Pthread

int main(int argc, char **argv)


{
int i, P=2;
pthread_t tid[P];
for(i = 0; i < P; i++) {
pthread_create(&(tid[i]), NULL, threadFunction, NULL);
}
for(i = 0; i < P; i++) {
pthread_join(tid[i], NULL);
}
return 0;
}

Florin Pop – Cristian Chilipirea


Pthread
void* threadFunction(void *arg)
{
int main(int argc, char **argv) a=a+1;
{ return NULL;
int i, P=2; }
pthread_t tid[P];
for(i = 0; i < P; i++) {
pthread_create(&(tid[i]), NULL, threadFunction, NULL);
}
for(i = 0; i < P; i++) {
pthread_join(tid[i], NULL);
}
return 0;
}

Florin Pop – Cristian Chilipirea


Pthread
void* threadFunction(void *arg)
{
int main(int argc, char **argv) a=a+1;
{ return NULL;
int i, P=2; }
pthread_t tid[P];
for(i = 0; i < P; i++) {
pthread_create(&(tid[i]), NULL, threadFunction, NULL);
}
for(i = 0; i < P; i++) {
pthread_join(tid[i], NULL);
}
return 0;
}

Florin Pop – Cristian Chilipirea


Pthread
void* threadFunction(void *arg)
{
int main(int argc, char **argv) a=a+1;
{ return NULL;
int i, P=2; }
pthread_t tid[P];
for(i = 0; i < P; i++) {
pthread_create(&(tid[i]), NULL, threadFunction, NULL);
}
for(i = 0; i < P; i++) {
pthread_join(tid[i], NULL);
}
return 0;
}

Florin Pop – Cristian Chilipirea


Pthread
void* threadFunction(void *arg)
{
int main(int argc, char **argv) a=a+1;
{ return NULL;
int i, P=2; }
pthread_t tid[P];
for(i = 0; i < P; i++) {
pthread_create(&(tid[i]), NULL, threadFunction, NULL);
}
for(i = 0; i < P; i++) {
pthread_join(tid[i], NULL); void* threadFunction(void *arg)
} {
a=a+1;
return 0; return NULL;
} }

Florin Pop – Cristian Chilipirea


Pthread
void* threadFunction(void *arg)
{
int main(int argc, char **argv) a=a+1;
{ return NULL;
int i, P=2; }
pthread_t tid[P];
for(i = 0; i < P; i++) {
pthread_create(&(tid[i]), NULL, threadFunction, NULL);
}
for(i = 0; i < P; i++) {
pthread_join(tid[i], NULL); void* threadFunction(void *arg)
} {
a=a+1;
return 0; return NULL;
} }

Florin Pop – Cristian Chilipirea


Pthread
void* threadFunction(void *arg)
{
int main(int argc, char **argv) a=a+1;
{ return NULL;
int i, P=2; }
pthread_t tid[P];
for(i = 0; i < P; i++) {
pthread_create(&(tid[i]), NULL, threadFunction, NULL);
}
for(i = 0; i < P; i++) {
pthread_join(tid[i], NULL); void* threadFunction(void *arg)
} {
a=a+1;
return 0; return NULL;
} }

Florin Pop – Cristian Chilipirea


Pthread
void* threadFunction(void *arg)
{
int main(int argc, char **argv) a=a+1;
{ return NULL;
int i, P=2; }
pthread_t tid[P];
for(i = 0; i < P; i++) {
pthread_create(&(tid[i]), NULL, threadFunction, NULL);
}
for(i = 0; i < P; i++) {
pthread_join(tid[i], NULL); void* threadFunction(void *arg)
} {
a=a+1;
return 0; return NULL;
} }

Florin Pop – Cristian Chilipirea


Pthread
void* threadFunction(void *arg)
{
int main(int argc, char **argv) a=a+1;
{ return NULL;
int i, P=2; }
pthread_t tid[P];
for(i = 0; i < P; i++) {
pthread_create(&(tid[i]), NULL, threadFunction, NULL);
}
for(i = 0; i < P; i++) {
pthread_join(tid[i], NULL); void* threadFunction(void *arg)
} {
a=a+1;
return 0; return NULL;
} }

Florin Pop – Cristian Chilipirea


Pthread
void* threadFunction(void *arg)
{
int main(int argc, char **argv) a=a+1;
{ return NULL;
int i, P=2; }
pthread_t tid[P];
for(i = 0; i < P; i++) {
pthread_create(&(tid[i]), NULL, threadFunction, NULL);
}
for(i = 0; i < P; i++) {
pthread_join(tid[i], NULL); void* threadFunction(void *arg)
} {
a=a+1;
return 0; return NULL;
} }

Florin Pop – Cristian Chilipirea


Pthread
void* threadFunction(void *arg)
{
int main(int argc, char **argv) a=a+1;
{ return NULL;
int i, P=2; }
pthread_t tid[P];
for(i = 0; i < P; i++) {
pthread_create(&(tid[i]), NULL, threadFunction, NULL);
}
for(i = 0; i < P; i++) {
pthread_join(tid[i], NULL); void* threadFunction(void *arg)
} {
a=a+1;
return 0; return NULL;
} }

Florin Pop – Cristian Chilipirea


Pthread
void* threadFunction(void *arg)
{
int main(int argc, char **argv) a=a+1;
{ return NULL;
int I, P=2; }
pthread_t tid[P];
for(i = 0; i < P; i++) {
pthread_create(&(tid[i]), NULL, threadFunction, NULL);
}
for(i = 0; i < P; i++) {
pthread_join(tid[i], NULL);
}
return 0;
}

Florin Pop – Cristian Chilipirea


Pthread
void* threadFunction(void *arg)
{
int main(int argc, char **argv) a=a+1;
{ return NULL;
int I, P=2; }
pthread_t tid[P];
for(i = 0; i < P; i++) {
pthread_create(&(tid[i]), NULL, threadFunction, NULL);
}
for(i = 0; i < P; i++) {
pthread_join(tid[i], NULL);
}
return 0;
}

Florin Pop – Cristian Chilipirea


Pthread
void* threadFunction(void *arg)
{
int main(int argc, char **argv) a=a+1;
{ return NULL;
int I, P=2; }
pthread_t tid[P];
for(i = 0; i < P; i++) {
pthread_create(&(tid[i]), NULL, threadFunction, NULL);
}
for(i = 0; i < P; i++) {
pthread_join(tid[i], NULL);
}
return 0;
}

Florin Pop – Cristian Chilipirea


Pthread

int main(int argc, char **argv)


{
int I, P=2;
pthread_t tid[P];
for(i = 0; i < P; i++) {
pthread_create(&(tid[i]), NULL, threadFunction, NULL);
}
for(i = 0; i < P; i++) {
pthread_join(tid[i], NULL);
}
return 0;
}

Florin Pop – Cristian Chilipirea


Pthread

int main(int argc, char **argv)


{
int I, P=2;
pthread_t tid[P];
for(i = 0; i < P; i++) {
pthread_create(&(tid[i]), NULL, threadFunction, NULL);
}
for(i = 0; i < P; i++) {
pthread_join(tid[i], NULL);
}
return 0;
}

Florin Pop – Cristian Chilipirea


Pthread

int main(int argc, char **argv)


{
int I, P=2;
pthread_t tid[P];
for(i = 0; i < P; i++) {
pthread_create(&(tid[i]), NULL, threadFunction, NULL);
}
for(i = 0; i < P; i++) {
pthread_join(tid[i], NULL);
}
return 0;
}

Florin Pop – Cristian Chilipirea


Pthread

int main(int argc, char **argv)


{
int I, P=2;
pthread_t tid[P];
for(i = 0; i < P; i++) {
pthread_create(&(tid[i]), NULL, threadFunction, NULL);
}
for(i = 0; i < P; i++) {
pthread_join(tid[i], NULL);
}
return 0;
}

Florin Pop – Cristian Chilipirea


Pthread

int main(int argc, char **argv)


{
int I, P=2;
pthread_t tid[P];
for(i = 0; i < P; i++) {
pthread_create(&(tid[i]), NULL, threadFunction, NULL);
}
for(i = 0; i < P; i++) {
pthread_join(tid[i], NULL);
}
return 0;
}

Florin Pop – Cristian Chilipirea


Pthread

int main(int argc, char **argv)


{
int I, P=2;
pthread_t tid[P];
for(i = 0; i < P; i++) {
pthread_create(&(tid[i]), NULL, threadFunction, NULL);
}
for(i = 0; i < P; i++) {
pthread_join(tid[i], NULL);
}
return 0;
}

Florin Pop – Cristian Chilipirea


Pthread

int main(int argc, char **argv)


{
int I, P=2;
pthread_t tid[P];
for(i = 0; i < P; i++) {
pthread_create(&(tid[i]), NULL, threadFunction, NULL);
}
for(i = 0; i < P; i++) {
pthread_join(tid[i], NULL);
}
return 0;
}

Florin Pop – Cristian Chilipirea


Florin Pop – Cristian Chilipirea
Race condition

Thread 1 Thread 2

a=a+2 a=a+2

What is the value of a?

Florin Pop – Cristian Chilipirea


Race condition
a=0

Thread 1 Thread 2

a=a+2 a=a+2

What is the value of a?

Florin Pop – Cristian Chilipirea


Race condition
a=0

Thread 1 Thread 2

a=a+2 a=a+2

What is the value of a?


4
Florin Pop – Cristian Chilipirea
Race condition
a=0

Thread 1 Thread 2

a=a+2 a=a+2

What is the value of a?


4 AND 2
Florin Pop – Cristian Chilipirea
Florin Pop – Cristian Chilipirea
Race condition
a=0

Thread 1 Thread 2

load(a, eax) load(a, eax)


eax = eax + 2 eax = eax + 2
write(a, eax) write(a, eax)

eax = eax =
Florin Pop – Cristian Chilipirea
Race condition
a=0

Thread 1 Thread 2

load(a, eax) load(a, eax)


eax = eax + 2 eax = eax + 2
write(a, eax) write(a, eax)

eax = 0 eax =
Florin Pop – Cristian Chilipirea
Race condition
a=0

Thread 1 Thread 2

load(a, eax) load(a, eax)


eax = eax + 2 eax = eax + 2
write(a, eax) write(a, eax)

eax = 0 eax = 0
Florin Pop – Cristian Chilipirea
Race condition
a=0

Thread 1 Thread 2

load(a, eax) load(a, eax)


eax = eax + 2 eax = eax + 2
write(a, eax) write(a, eax)

eax = 2 eax = 0
Florin Pop – Cristian Chilipirea
Race condition
a=0

Thread 1 Thread 2

load(a, eax) load(a, eax)


eax = eax + 2 eax = eax + 2
write(a, eax) write(a, eax)

eax = 2 eax = 2
Florin Pop – Cristian Chilipirea
Race condition
a=2

Thread 1 Thread 2

load(a, eax) load(a, eax)


eax = eax + 2 eax = eax + 2
write(a, eax) write(a, eax)

eax = 2 eax = 2
Florin Pop – Cristian Chilipirea
Race condition
a=2

Thread 1 Thread 2

load(a, eax) load(a, eax)


eax = eax + 2 eax = eax + 2
write(a, eax) write(a, eax)

eax = 2 eax = 2
Florin Pop – Cristian Chilipirea
Florin Pop – Cristian Chilipirea
Race condition
a=0

Thread 1 Thread 2

load(a, eax) load(a, eax)


eax = eax + 2 eax = eax + 2
write(a, eax) write(a, eax)

eax = eax =
Florin Pop – Cristian Chilipirea
Race condition
a=0

Thread 1 Thread 2

load(a, eax) load(a, eax)


eax = eax + 2 eax = eax + 2
write(a, eax) write(a, eax)

eax = 0 eax =
Florin Pop – Cristian Chilipirea
Race condition
a=0

Thread 1 Thread 2

load(a, eax) load(a, eax)


eax = eax + 2 eax = eax + 2
write(a, eax) write(a, eax)

eax = 2 eax =
Florin Pop – Cristian Chilipirea
Race condition
a=2

Thread 1 Thread 2

load(a, eax) load(a, eax)


eax = eax + 2 eax = eax + 2
write(a, eax) write(a, eax)

eax = 2 eax =
Florin Pop – Cristian Chilipirea
Race condition
a=2

Thread 1 Thread 2

load(a, eax) load(a, eax)


eax = eax + 2 eax = eax + 2
write(a, eax) write(a, eax)

eax = 2 eax = 2
Florin Pop – Cristian Chilipirea
Race condition
a=2

Thread 1 Thread 2

load(a, eax) load(a, eax)


eax = eax + 2 eax = eax + 2
write(a, eax) write(a, eax)

eax = 2 eax = 4
Florin Pop – Cristian Chilipirea
Race condition
a=4

Thread 1 Thread 2

load(a, eax) load(a, eax)


eax = eax + 2 eax = eax + 2
write(a, eax) write(a, eax)

eax = 2 eax = 4
Florin Pop – Cristian Chilipirea
Florin Pop – Cristian Chilipirea
Race condition
a=0

Thread 1 Thread 2

load(a, eax) load(a, eax)


eax = eax + 2 eax = eax + 2
write(a, eax) write(a, eax)

eax = eax =
Florin Pop – Cristian Chilipirea
Race condition
a=0

Thread 1 Thread 2

load(a, eax) load(a, eax)


eax = eax + 2 eax = eax + 2
write(a, eax) write(a, eax)

eax = 0 eax = 0
Florin Pop – Cristian Chilipirea
Race condition
a=0

Thread 1 Thread 2

load(a, eax) load(a, eax)


eax = eax + 2 eax = eax + 2
write(a, eax) write(a, eax)

eax = 2 eax = 2
Florin Pop – Cristian Chilipirea
Race condition
a=2

Thread 1 Thread 2

load(a, eax) load(a, eax)


eax = eax + 2 eax = eax + 2
write(a, eax) write(a, eax)

eax = 2 eax = 2
Florin Pop – Cristian Chilipirea
Race condition
a=2

Thread 1 Thread 2

load(a, eax) load(a, eax)


eax = eax + 2 eax = eax + 2
write(a, eax) write(a, eax)

eax = 2 eax = 2
Florin Pop – Cristian Chilipirea
Race condition
a=2

Thread 1 Thread 2

load(a, eax) load(a, eax)


eax = eax + 2 eax = eax + 2
write(a, eax) write(a, eax)

eax = 2 CREW eax = 2


Florin Pop – Cristian Chilipirea
Florin Pop – Cristian Chilipirea
Synchronization primitives

▪Atomics
▪Semaphore
‒ Binary semaphore (Mutex)
‒ Critical section
▪Barrier

Florin Pop – Cristian Chilipirea


Atomics
▪ Fie variabilelor de 64 biți pe un procesor 64 biți C = A + B

load(A, eax)
load(B, ebx)
eax = eax + ebx
write(C, eax)

Florin Pop – Cristian Chilipirea


Atomics
▪ Fie variabilelor de 64 biți pe un procesor 32 biți C = A + B
load(A[0], eax)
load(B[0], ebx)
eax = eax + ebx
write(C[0], eax)
load(A[1], eax)
load(B[1], ebx)
eax = eax + ebx
write(C[1], eax)

Florin Pop – Cristian Chilipirea


Atomics
▪ Fie variabilelor de 64 biți pe un procesor 32 biți C = A + B
load(A[0], eax)
load(B[0], ebx)
eax = eax + ebx Putem avea doar
write(C[0], eax) jumătate de C
load(A[1], eax) modificat
load(B[1], ebx)
eax = eax + ebx
write(C[1], eax)

Florin Pop – Cristian Chilipirea


Atomics
▪ Fie variabilelor de 64 biți pe un procesor 32 biți C = A + B
load(A[0], eax)
load(B[0], ebx)
eax = eax + ebx Atomicitatea asigură
write(C[0], eax) că C va fi vizibil doar
load(A[1], eax) complet modificat, sau
load(B[1], ebx) complet nemodificat.
eax = eax + ebx
write(C[1], eax)

Florin Pop – Cristian Chilipirea


Mutual exclusion - mutex

Florin Pop – Cristian Chilipirea


Mutual exclusion - Dekker’s solution

Theodorus (Dirk) J. Dekker


Florin Pop – Cristian Chilipirea
Mutual exclusion – Dijsktra’s Solution

Florin Pop – Cristian Chilipirea


Dekker’s Solution

wants_to_enter[0] = true
while wants_to_enter[1] {
if turn != 0 {
wants_to_enter[0] = false
while turn != 0 { // busy wait }
wants_to_enter[0] = true
}
}
// critical section ...
turn = 1
wants_to_enter[0] = false
Florin Pop – Cristian Chilipirea
Dijsktra’s Solution
b[i] = fals
while(sw[i]) {
sw[i] = F
if (k!=i) {
c[i] = true
if(b[k]) lock()
k=i
sw[i] = T
} else {
c[i] = false
for(j=0;j<N;j++)
if(j!=i && !c[j])
sw[i] = T
}
}
//critical
b[i] = true
c[i] = true unlock()
Florin Pop – Cristian Chilipirea
flag[0] =
;
flag[0] =
;

Peterson’s Solution

flag[0] = true;
P0_gate: turn = 1;
while (flag[1] == && turn == 1) { // busy wait }
// critical section ...
flag[0] = false;

Florin Pop – Cristian Chilipirea


Hardware assisted Solution

while (test_and_set(lock));
// critical section
lock = 0

Florin Pop – Cristian Chilipirea


Race condition - solution
a=0
Thread 1 Thread 2
lock(locka) lock(locka)
load(a, eax) load(a, eax)
eax = eax + 2 eax = eax + 2
write(a, eax) write(a, eax)
unlock(locka) unlock(locka)
eax = 0 eax = 0
Florin Pop – Cristian Chilipirea
Race condition - solution ?
a=0
Thread 1 Thread 2
lock(locka) lock(locka)
load(a, eax) load(a, eax)
eax = eax + 2 eax = eax + 2
write(a, eax) write(a, eax)
unlock(locka) unlock(locka)
eax = 0 eax = 2
Florin Pop – Cristian Chilipirea
Race condition - solution OK
a=0
Thread 1 Thread 2
lock(locka) lock(locka)
load(a, eax) load(a, eax)
eax = eax + 2 eax = eax + 2
write(a, eax) write(a, eax)
unlock(locka) unlock(locka)
eax = 0 eax = 2
Florin Pop – Cristian Chilipirea
Race condition - solution ?
a=2
Thread 1 Thread 2
lock(locka) lock(locka)
load(a, eax) load(a, eax)
eax = eax + 2 eax = eax + 2
write(a, eax) write(a, eax)
unlock(locka) unlock(locka)
eax = 0 eax = 2
Florin Pop – Cristian Chilipirea
Race condition - solution OK
a=2
Thread 1 Thread 2
lock(locka) lock(locka)
load(a, eax) load(a, eax)
eax = eax + 2 eax = eax + 2
write(a, eax) write(a, eax)
unlock(locka) unlock(locka)
eax = 0 eax = 2
Florin Pop – Cristian Chilipirea
Race condition - solution ?
a=0
Thread 1 Thread 2
lock(locka) lock(locka)
load(a, eax) load(a, eax)
eax = eax + 2 eax = eax + 2
write(a, eax) write(a, eax)
unlock(locka) unlock(locka)
eax = 2 eax = 0
Florin Pop – Cristian Chilipirea
Race condition - solution OK
a=0
Thread 1 Thread 2
lock(locka) lock(locka)
load(a, eax) load(a, eax)
eax = eax + 2 eax = eax + 2
write(a, eax) write(a, eax)
unlock(locka) unlock(locka)
eax = 2 eax = 0
Florin Pop – Cristian Chilipirea
Race condition - solution ?
a=2
Thread 1 Thread 2
lock(locka) lock(locka)
load(a, eax) load(a, eax)
eax = eax + 2 eax = eax + 2
write(a, eax) write(a, eax)
unlock(locka) unlock(locka)
eax = 2 eax = 0
Florin Pop – Cristian Chilipirea
Race condition - solution OK
a=2
Thread 1 Thread 2
lock(locka) lock(locka)
load(a, eax) load(a, eax)
eax = eax + 2 eax = eax + 2
write(a, eax) write(a, eax)
unlock(locka) unlock(locka)
eax = 2 eax = 0
Florin Pop – Cristian Chilipirea
Race condition - solution ?
a=4
Thread 1 Thread 2
lock(locka) lock(locka)
load(a, eax) load(a, eax)
eax = eax + 2 eax = eax + 2
write(a, eax) write(a, eax)
unlock(locka) unlock(locka)
eax = 2 eax = 2
Florin Pop – Cristian Chilipirea
Race condition - solution OK
a=4
Thread 1 Thread 2
lock(locka) lock(locka)
load(a, eax) load(a, eax)
eax = eax + 2 eax = eax + 2
write(a, eax) write(a, eax)
unlock(locka) unlock(locka)
eax = 2 eax = 2
Florin Pop – Cristian Chilipirea
Race condition - solution ?
a=0
Thread 1 Thread 2
lock(locka) lock(locka)
load(a, eax) load(a, eax)
eax = eax + 2 eax = eax + 2
write(a, eax) write(a, eax)
unlock(locka) unlock(locka)
eax = 0 eax = 2
Florin Pop – Cristian Chilipirea
Race condition - solution
a=0
Thread 1 Thread 2
lock(locka) lock(locka)
load(a, eax) load(a, eax)
eax = eax + 2 eax = eax + 2
write(a, eax) write(a, eax)
unlock(locka) unlock(locka)
eax = 0 eax = 2
Florin Pop – Cristian Chilipirea
Mutex Pthread

ÎN MAIN
Înainte de a porni thread-urile

pthread_mutex_t mutex;
pthread_mutex_init(&mutex, NULL);

Florin Pop – Cristian Chilipirea


Mutex Pthread

pthread_mutex_t mutex;
pthread_mutex_init(&mutex, NULL);

Poate fi folosit să anunțe că


acest mutex e împărțit mai
multor procese

Florin Pop – Cristian Chilipirea


Mutex Pthread

pthread_mutex_lock(&mutex);
load(a, eax)
eax = eax + 2
write(a, eax)
pthread_mutex_unlock(&mutex);

Florin Pop – Cristian Chilipirea


Mutex Pthread

ÎN MAIN
După ce au terminat thread-urile

pthread_mutex_destroy(&mutex);

Florin Pop – Cristian Chilipirea


Florin Pop – Cristian Chilipirea
Semaphore

ÎN MAIN
Înainte de a porni thread-urile

sem_t semaphore;
int semaphore_value= 4;
sem_init(& semaphore, 0, semaphore_value);

Florin Pop – Cristian Chilipirea


Semaphore

4
sem_wait(&semaphore);

P() sau Proberen


- Dijsktra

by Cristian Chilipirea
Semaphore

4
sem_wait(&semaphore);

by Cristian Chilipirea
Semaphore

4
sem_wait(&semaphore);

by Cristian Chilipirea
Semaphore

3
sem_wait(&semaphore);

by Cristian Chilipirea
Semaphore
Nu contează că doua thread-uri au
ajuns simultan la semafor, acesta
este protejat, la fel ca un mutex.

2
sem_wait(&semaphore);

by Cristian Chilipirea
Semaphore

1
sem_wait(&semaphore);

by Cristian Chilipirea
Semaphore

0
sem_wait(&semaphore);

by Cristian Chilipirea
Semaphore

0
sem_wait(&semaphore);

by Cristian Chilipirea
Semaphore – A different way of thinking

Un semafor are un set de token-uri.

sem_wait(&semaphore);

by Cristian Chilipirea
Semaphore – A different way of thinking

sem_wait(&semaphore);

by Cristian Chilipirea
Semaphore – A different way of thinking

sem_wait(&semaphore);

by Cristian Chilipirea
Semaphore – A different way of thinking

sem_wait(&semaphore);

by Cristian Chilipirea
Semaphore – A different way of thinking

sem_wait(&semaphore);

by Cristian Chilipirea
Semaphore – Signaling

sem_wait(&semaphore); -1

sem_post(&semaphore);

sem_post(&semaphore);
V() sau Verogen
- Dijsktra

by Cristian Chilipirea
Semaphore – Signaling

sem_wait(&semaphore); -1

sem_post(&semaphore);

sem_post(&semaphore);

by Cristian Chilipirea
Semaphore – Signaling

sem_wait(&semaphore); -1

sem_post(&semaphore);

sem_post(&semaphore);

by Cristian Chilipirea
Semaphore – Signaling

sem_wait(&semaphore); 0

sem_post(&semaphore);

sem_post(&semaphore);

by Cristian Chilipirea
Semaphore – Signaling

sem_wait(&semaphore); 1

sem_post(&semaphore);

sem_post(&semaphore);

by Cristian Chilipirea
Semaphore – Signaling

sem_wait(&semaphore); 0

sem_post(&semaphore);

sem_post(&semaphore);

by Cristian Chilipirea
Semaphore

ÎN MAIN
După ce au terminat thread-urile

sem_destroy(& semaphore);

Florin Pop – Cristian Chilipirea


Barrier

Florin Pop – Cristian Chilipirea


Barrier

ÎN MAIN
Înainte de a porni thread-urile

pthread_barrier_t barrier;
int num_threads = 5;
pthread_barrier_init(&barrier, NULL, num_threads);

Florin Pop – Cristian Chilipirea


Barrier

pthread_barrier_wait(&barrier);

by Cristian Chilipirea
Barrier

pthread_barrier_wait(&barrier);

5
For all threads, all code here
is executed before any code here

by Cristian Chilipirea
Barrier

pthread_barrier_wait(&barrier);

by Cristian Chilipirea
Barrier

pthread_barrier_wait(&barrier);

by Cristian Chilipirea
Barrier

pthread_barrier_wait(&barrier);

by Cristian Chilipirea
Barrier

pthread_barrier_wait(&barrier);

by Cristian Chilipirea
Barrier

pthread_barrier_wait(&barrier);

by Cristian Chilipirea
Barrier

pthread_barrier_wait(&barrier);

by Cristian Chilipirea
Barrier

pthread_barrier_wait(&barrier);

by Cristian Chilipirea
Barrier

pthread_barrier_wait(&barrier);

by Cristian Chilipirea
Barrier

pthread_barrier_wait(&barrier);

by Cristian Chilipirea
Barrier

pthread_barrier_wait(&barrier);

by Cristian Chilipirea
Barrier

pthread_barrier_wait(&barrier);

by Cristian Chilipirea
Barrier
Cum știe o barieră când să se reseteze?

O soluție ar fi:
Reusable Barrier in
The Little Book of Semaphores
By Allen B. Downey

pthread_barrier_wait(&barrier);

by Cristian Chilipirea
Barrier

ÎN MAIN
După ce au terminat thread-urile

pthread_barrier_destroy(&barrier);

Florin Pop – Cristian Chilipirea


Florin Pop – Cristian Chilipirea
Some problems can not be parallelized
Calculating the hash of a hash of a hash …
of a string.

Deep First Search

Huffman decoding

Outer loops of most simulations

P complete problems
Florin Pop – Cristian Chilipirea
Splitting a problem to make it parallel

Sunt o serie de probleme care sunt


extrem de ușor paralelizabile.

Embarrassingly parallel

Florin Pop – Cristian Chilipirea


Embarrassingly parallel problems

Multiplicare unui vector cu un scalar

9 6 9 4 2 7 6 5 6 1

*3
27 18 27 12 6 21 18 15 18 3

Florin Pop – Cristian Chilipirea


Embarrassingly parallel problems

Toate calculele pot fi efectuate în


același timp

9 6 9 4 2 7 6 5 6 1

*3
27 18 27 12 6 21 18 15 18 3

Florin Pop – Cristian Chilipirea


Embarrassingly parallel problems

Câte elemente sunt?

9 6 9 4 2 7 6 5 6 1

Florin Pop – Cristian Chilipirea


Embarrassingly parallel problems

Câte elemente sunt?

9 6 9 4 2 7 6 5 6 … 1

Florin Pop – Cristian Chilipirea


Embarrassingly parallel problems

Câte elemente sunt? N

9 6 9 4 2 7 6 5 6 … 1

Florin Pop – Cristian Chilipirea


Embarrassingly parallel problems

Dar câte elemente de procesare?

9 6 9 4 2 7 6 5 6 … 1

Florin Pop – Cristian Chilipirea


Embarrassingly parallel problems

Dar câte elemente de procesare? P


9 6 9 4 2 7 6 5 6 … 1

Florin Pop – Cristian Chilipirea


Embarrassingly parallel problems

Dar câte thread-uri?

9 6 9 4 2 7 6 5 6 … 1

Florin Pop – Cristian Chilipirea


Embarrassingly parallel problems

Dar câte thread-uri? P


9 6 9 4 2 7 6 5 6 … 1

În majoritatea cazurilor obținem performanță maximă când


numărul de thread-uri este egal cu numărul de elemente de
procesare, sau core-uri.

Florin Pop – Cristian Chilipirea


Embarrassingly parallel problems

Cum este P față de N?

9 6 9 4 2 7 6 5 6 … 1

Florin Pop – Cristian Chilipirea


Embarrassingly parallel problems

P << N
9 6 9 4 2 7 6 5 6 … 1

Florin Pop – Cristian Chilipirea


Embarrassingly parallel problems

Caz concret: P = 2
Cum împărțim?
9 6 9 4 2 7 6 5 6 … 1

Florin Pop – Cristian Chilipirea


Embarrassingly parallel problems

Caz concret: P = 2
Cum împărțim?
9 6 9 4 2 7 6 5 6 … 1

Thread 1 Thread 2

Florin Pop – Cristian Chilipirea


Embarrassingly parallel problems

Caz concret: P = 2
Cum împărțim?
9 6 9 4 2 7 6 5 6 … 1

Thread 1 Thread 2

Florin Pop – Cristian Chilipirea


Embarrassingly parallel problems

Caz concret: P = 2
Cum împărțim?
9 6 9 4 2 7 6 5 6 … 1

Thread 1 Thread 2

Florin Pop – Cristian Chilipirea


Embarrassingly parallel problems

Caz concret: P = 2
Cum împărțim? Putem și random
9 6 9 4 2 7 6 5 6 … 1

Thread 1 Thread 2

Florin Pop – Cristian Chilipirea


Embarrassingly parallel problems

Caz concret: P = 2
Cum împărțim?
9 6 9 4 2 7 6 5 6 … 1

Thread 1 Thread 2

Florin Pop – Cristian Chilipirea


Embarrassingly parallel problems

Caz concret: P = 2
Cum împărțim?
9 6 9 4 2 7 6 5 6 … 1

Este utilă?
Thread 1 Thread 2

Florin Pop – Cristian Chilipirea


Embarrassingly parallel problems

Caz concret: P = 2
Cum împărțim?
9 6 9 4 2 7 6 5 6 … 1

Ce ne dorim?
Thread 1 Thread 2

Florin Pop – Cristian Chilipirea


Embarrassingly parallel problems

Caz concret: P = 2
Cum împărțim?
9 6 9 4 2 7 6 5 6 … 1

Ce ne dorim?
Thread 1 Thread 2

Aproximativ același număr elemente


Florin Pop – Cristian Chilipirea
Embarrassingly parallel problems

Aproximativ N/P elemente

9 6 9 4 2 7 6 5 6 … 1

Thread 1 Thread 2

Florin Pop – Cristian Chilipirea


Embarrassingly parallel problems

Aproximativ N/P elemente

9 6 9 4 2 7 6 5 6 … 1
Dacă N nu se divide perfect la P?
Thread 1 Thread 2

Florin Pop – Cristian Chilipirea


Embarrassingly parallel problems

Aproximativ N/P elemente


Dacă N nu se divide perfect la P?
1
6 8
4 2 7 4 9 2
9 6 9 5 6 3
Thread 1 Thread 2
Florin Pop – Cristian Chilipirea
Embarrassingly parallel problems

floor(N/P) elemente floor(15/2) = 7

1
6 8
4 2 7 4 9 2
9 6 9 5 6 3
Thread 1 Thread 2
Florin Pop – Cristian Chilipirea
Embarrassingly parallel problems

ceil(N/P) elemente ceil(15/2) = 8

6 5 8 1
4 2 7 4 9 2
9 6 9 6 3
Thread 1 Thread 2
Florin Pop – Cristian Chilipirea
Embarrassingly parallel problems

A = floor(N/P)

PA

0 A 2A N

Florin Pop – Cristian Chilipirea


Embarrassingly parallel problems

A = ceil(N/P)

PA

0 A 2A N

Florin Pop – Cristian Chilipirea


Embarrassingly parallel problems
Formule elegante:
Tid este identificator de thread, are valori de la 0
la P
start = Tid * ceil(N/P)
end = min(N, (Tid+1) * ceil(N/P)) PA

0 A 2A N

Florin Pop – Cristian Chilipirea

You might also like