Για να δούμε, δουλεύει αυτό;

Δζληθό Μεηζόβην Πνιπηερλείν
Σρνιή Ζιεθηξνιόγσλ Μερ. θαη Μεραληθώλ Υπνινγηζηώλ
Δξγαζηήξην Υπνινγηζηηθώλ Σπζηεκάησλ
3ε Δξγαζηεξηαθή Άζθεζε:
Σπγρξνληζκόο
Λεηηνπξγηθά Σπζηήκαηα Υπνινγηζηώλ
7ν Δμάκελν, 2014-2015
Σύλνςε
 Πξνβιήκαηα ζπγρξνληζκνύ
 Υινπνηήζεηο κε POSIX Threads
 POSIX Mutexes, Semaphores, Condition Variables
θαη GCC atomic operations
 Ε1: Σπγρξνληζκόο ζε ππάξρνληα θώδηθα
 simplesync.c
 Με POSIX mutexes θαη GCC atomic ops
 Ε2: Παξαιιεινπνίεζε ππάξρνληα θώδηθα
 Σπγρξνληζκόο λεκάησλ γηα παξάιιειν ππνινγηζκό
 Ε3: Δπίιπζε πξνβιήκαηνο ζπγρξνληζκνύ
 Με δεδνκέλνπο πεξηνξηζκνύο γηα ηα λήκαηα
Σύλνςε
 Πξνβιήκαηα ζπγρξνληζκνύ
 Υινπνηήζεηο κε POSIX Threads
 POSIX Mutexes, Semaphores, Condition Variables
θαη GCC atomic operations
 Ε1: Σπγρξνληζκόο ζε ππάξρνληα θώδηθα
 simplesync.c
 Με POSIX mutexes θαη GCC atomic ops
 Ε2: Παξαιιεινπνίεζε ππάξρνληα θώδηθα
 Σπγρξνληζκόο λεκάησλ γηα παξάιιειν ππνινγηζκό
 Ε3: Δπίιπζε πξνβιήκαηνο ζπγρξνληζκνύ
 Με δεδνκέλνπο πεξηνξηζκνύο γηα ηα λήκαηα
Γεκηνπξγία λεκάησλ ζηα POSIX
Threads
 Γεκηνπξγία κε pthread_create()
 int pthread_create(pthread_t * thread, pthread_attr_t * attr,
void * (*start_routine)(void *), void * arg);
 π.ρ. pthread_create(&tid, &attr, thread_fn, arg)
 Αλακνλή γηα ηεξκαηηζκό (pthread_exit()) κε
pthread_join()
thread1
pthread_create
thread1
thread2
Compute
thread2
pthread_join thread1
thread2
(stopped)
pthread_exit
Σύλνςε
 Πξνβιήκαηα ζπγρξνληζκνύ
 Υινπνηήζεηο κε POSIX Threads
 POSIX Mutexes, Semaphores, Condition Variables
θαη GCC atomic operations
 Ε1: Σπγρξνληζκόο ζε ππάξρνληα θώδηθα
 simplesync.c
 Με POSIX mutexes θαη GCC atomic ops
 Ε2: Παξαιιεινπνίεζε ππάξρνληα θώδηθα
 Σπγρξνληζκόο λεκάησλ γηα παξάιιειν ππνινγηζκό
 Ε3: Δπίιπζε πξνβιήκαηνο ζπγρξνληζκνύ
 Με δεδνκέλνπο πεξηνξηζκνύο γηα ηα λήκαηα
Μεραληζκνί (POSIX)
 POSIX Threads <pthread.h>
 pthread_create(), pthread_join()
 POSIX Mutexes <pthread.h>
 pthread_mutex_init()
 POSIX (unnamed) Semaphores <semaphore.h>
 Manpages: sem_overview(7), sem_init(3), sem_post(3),
sem_wait(3).
 POSIX condition variables:
 pthread_cond_init(), pthread_cond_wait(),
pthread_cond_signal(), pthread_cond_broadcast()
 Εγκαηαζηήζηε ηα παθέηα manpages-posix, manpages-posix-dev:
man –a sem_post
Μεραληζκνί (GCC atomic operations)
 GCC atomic operations
 http://gcc.gnu.org/onlinedocs/gcc-4.1.2/gcc/AtomicBuiltins.html
 Δηδηθέο εληνιέο (builtins) / ζπλαξηήζεηο γηα
αηομική ππόζβαζη
 __sync_add_and_fetch(),
__sync_sub_and_fetch(),
…
Σύλνςε
 Πξνβιήκαηα ζπγρξνληζκνύ
 Υινπνηήζεηο κε POSIX Threads
 POSIX Mutexes, Semaphores, Condition Variables
θαη GCC atomic operations
 Ε1: Σπγρξνληζκόο ζε ππάξρνληα θώδηθα
 simplesync.c
 Με POSIX mutexes θαη GCC atomic ops
 Ε2: Παξαιιεινπνίεζε ππάξρνληα θώδηθα
 Σπγρξνληζκόο λεκάησλ γηα παξάιιειν ππνινγηζκό
 Ε3: Δπίιπζε πξνβιήκαηνο ζπγρξνληζκνύ
 Με δεδνκέλνπο πεξηνξηζκνύο γηα ηα λήκαηα
Ε1: Σπγρξνληζκόο ζε ππάξρνληα
θώδηθα
 Γύν λήκαηα: TINCREASE, TDECREASE
 Απμάλνπλ/κεηώλνπλ ην κοινό n, N θνξέο, αληίζηνηρα
 Αξρηθή ηηκή n = 0. Σρήκα ζπγρξνληζκνύ ώζηε
Τν n λα παξακείλεη 0 κεηά ην ηέινο ηεο εθηέιεζήο ηνπο.
enter
exit
for (Ν θοπέρ) {
for (Ν θοπέρ) {
++ n;
- - n;
}
}
TINCREASE
TDECREASE
n
Ε1: Σπγρξνληζκόο ζην simplesync.c
 Δύο πινπνηήζεηο
 Ζ1α. POSIX mutexes
 Ζ1β. GCC atomic operations: __sync_*()
for (Ν θοπέρ) {
enter
exit
for (Ν θοπέρ) {
++ (*ip);
- - (*ip);
}
}
TINCREASE
TDECREASE
n
*ip
Ε1: Σπγρξνληζκόο ζε ππάξρνληα
θώδηθα
 Ζ1α. POSIX mutexes/semaphores
 Κώδηθαο μόνο ζηα ζεκεία “enter”, “exit”
 Καηάιιεια αξρηθνπνηεκέλα mutexes ή ζεκαθόξνη
 wait(), signal() ζε απηνύο
 Φσξίο αιιαγή ηνπ θώδηθα πνπ πεηξάδεη ηε
κεηαβιεηή
 Ζ1β. GCC atomic operations
 Αλλαγή ηνπ ηξόπνπ πξόζβαζεο ζηε κεηαβιεηή
 Απαηηείηαη πιένλ θώδηθαο ζηα “enter”, “exit”;
Ε1: Σπγρξνληζκόο ζην simplesync.c
 Δύο πινπνηήζεηο
 Ζ1α. POSIX mutexes
 Ζ1β. GCC atomic operations: __sync_*()
for (Ν θοπέρ) {
enter
exit
for (Ν θοπέρ) {
++ (*ip);
- - (*ip);
}
}
TINCREASE
TDECREASE
n
*ip
Σύλνςε
 Πξνβιήκαηα ζπγρξνληζκνύ
 Υινπνηήζεηο κε POSIX Threads
 POSIX Mutexes, Semaphores, Condition Variables
θαη GCC atomic operations
 Ε1: Σπγρξνληζκόο ζε ππάξρνληα θώδηθα
 simplesync.c
 Με POSIX mutexes θαη GCC atomic ops
 Ε2: Παξαιιεινπνίεζε ππάξρνληα θώδηθα
 Σπγρξνληζκόο λεκάησλ γηα παξάιιειν ππνινγηζκό
 Ε3: Δπίιπζε πξνβιήκαηνο ζπγρξνληζκνύ
 Με δεδνκέλνπο πεξηνξηζκνύο γηα ηα λήκαηα
Ε2: Παξαιιεινπνίεζε: the Mandelbrot Set
The Mandelbrot Set: Οξηζκόο
The Mandelbrot Set: ζρεδίαζε
 Γηα θάζε ζεκείν c κηαο πεξηνρήο ηνπ κηγαδηθνύ
επηπέδνπ
 Δπαλαιεπηηθόο ππνινγηζκόο ηνπ
zn+1= zn2 + c, z0 = 0, κέρξη λα μεθύγεη ην |zn|
 Κάζε pixel ρξσκαηίδεηαη αλάινγα κε ηνλ αξηζκό ησλ
επαλαιήςεσλ πνπ ρξεηάζηεθαλ, ή nmax
 Υπάξρνπλ θη άιινη αιγόξηζκνη
The Mandelbrot Set: θώδηθαο
 Σαο δίλεηαη θώδηθαο (mandel.c) πνπ δσγξαθίδεη
εηθόλεο από ην ζύλνιν Mandelbrot
 Σην ηεξκαηηθό, κε ρξσκαηηζηνύο ραξαθηήξεο
 Κάζε εηθόλα είλαη πιάηνπο x_chars, ύςνπο
y_chars
 Ζ ζρεδίαζε γίλεηαη επαλαιεπηηθά, γηα θάζε
γξακκή
 Σπλαξηήζεηο
 compute_and_output_mandel_line(fd, line)
 mandel_iterations_at_point(x, y, MAX)
 set_xterm_color(fd, color)
The Mandelbrot Set: Παξαιιεινπνίεζε
Τ0
Τ1
Τ0
Τ1
Τ0
Τ1
Τ0
Τ1
Τ0
Τ1
Τ0
Τ1
Τ0
Τ1
Τ0
Τ1
Τ0
Τ1
 Καηαλνκή ηνπ θνξηίνπ
y_chars
αλά γραμμές
 Ξεθηλώληαο από ην
πξώην λήκα, αλάζεζε
γξακκώλ κε θπθιηθή
επαλαθνξά
 Νήκα i από N:
i, i + N , i + 2*N, i + 3*N
θιπ
Σςγσπονιζμόρ;
x_chars
Σύλνςε
 Πξνβιήκαηα ζπγρξνληζκνύ
 Υινπνηήζεηο κε POSIX Threads
 POSIX Mutexes, Semaphores, Condition Variables
θαη GCC atomic operations
 Ε1: Σπγρξνληζκόο ζε ππάξρνληα θώδηθα
 simplesync.c
 Με POSIX mutexes θαη GCC atomic ops
 Ε2: Παξαιιεινπνίεζε ππάξρνληα θώδηθα
 Σπγρξνληζκόο λεκάησλ γηα παξάιιειν ππνινγηζκό
 Ε3: Δπίιπζε πξνβιήκαηνο ζπγρξνληζκνύ
 Με δεδνκέλνπο πεξηνξηζκνύο γηα ηα λήκαηα
Ε3: Δπίιπζε πξνβιήκαηνο
ζπγρξνληζκνύ
 Έλα νηπιαγωγείο (Kindergarten)
 Δάζκαλοι θαη παιδιά.
 Καζνξηζκέλε κέγηζηε αλαινγία παηδηώλ αλά
δάζθαιν: R παηδηά αλά δάζθαιν, π.ρ. 3:1.
 Γεδνκέλε πινπνίεζε
 N λήκαηα: C λήκαηα πξνζνκνηώλνπλ παηδηά, ηα
ππόινηπα N - C δαζθάινπο.
 Σαο δίλεηαη θώδηθαο, πνπ απνηπγράλεη.
Ε3: Δπίιπζε πξνβιήκαηνο
ζπγρξνληζκνύ
“entering”
“entering”
“entering”
“entering”
C_ENTER()
C_ENTER()
T_ENTER()
T_ENTER()
verify()
verify()
verify()
verify()
C_EXIT()
C_EXIT()
T_EXIT()
T_EXIT()
“exited”
“exited”
“exited”
“exited”
TC
…
TC
TT
Struct kindergarten_struct {
/* … */
};
TT
Ε3: Δπίιπζε πξνβιήκαηνο
ζπγρξνληζκνύ
 Σπλζήθεο αιιαγήο θαηάζηαζεο:
 Παηδί:
• Μπαίλεη -> ππάξρνπλ ηνπιάρηζηνλ (C+1)/R δάζθαινη
γηα λα κε ππνζηεξίμνπλ;
• Βγαίλεη -> άλεπ όξσλ (ελεκεξώλεη αλ ζέιεη θάπνηνο
δάζθαινο λα βγεη αλ (N - C - 1) * R >= C)
 Γάζθαινο:
• Μπαίλεη -> αλ πεξηκέλνπλ παηδηά, κπνξνύλ λα κπνύλ
κέρξη R
• Βγαίλεη -> ππάξρνπλ αξθεηνί δάζθαινη γηα λα
ππνζηεξίμνπλ ηα παηδηά; (N - C - 1) * R >= C.
Ε3: Δπίιπζε πξνβιήκαηνο
ζπγρξνληζκνύ
Παιδιά: αναμονή για είζοδο
Δάζκαλορ
Παιδί
Νηπιαγωγείο
Δάζκαλοι: αναμονή για έξοδο
Παιδί
Ε3: Δπίιπζε πξνβιήκαηνο
ζπγρξνληζκνύ (condition variables)
pthread_mutex_t Lock;
pthread_cond_t cond;
int counter = 0;
/* Thread A */
pthread_mutex_lock(&Lock);
while (counter < 10)
pthread_cond_wait(&cond,
&Lock);
pthread_mutex_unlock(&Lock);
/* Thread B */
pthread_mutex_lock(&Lock);
counter++;
If (counter >= 10)
pthread_cond_signal(&cond);
pthread_mutex_unlock(&Lock);
Δξσηήζεηο;
θαη ζηε ιίζηα:
OS@lists.cslab.ece.ntua.gr