Συγχρονισμός. Εθνικό Μετσόβιο Πολυτεχνείο Σχολή Ηλεκτρολόγων Μηχ. και Μηχανικών Υπολογιστών Εργαστήριο Υπολογιστικών Συστημάτων
|
|
- Υγίνος Παπακωνσταντίνου
- 7 χρόνια πριν
- Προβολές:
Transcript
1 Εθνικό Μετσόβιο Πολυτεχνείο Σχολή Ηλεκτρολόγων Μηχ. και Μηχανικών Υπολογιστών Εργαστήριο Υπολογιστικών Συστημάτων Συγχρονισμός 9 ο Εξάμηνο
2 Σύνοψη Το πρόβλημα του συγχρονισμού Βασικοί μηχανισμοί Κλειδώματα και υλοποιήσεις Condition variables Τακτικές συγχρονισμού Coarse-grain locking Fine-grain locking Optimistic synchronization Lazy synchronization Non-blocking synchronization 2
3 Η ανάγκη για συγχρονισμό Ταυτόχρονη πρόσβαση σε κοινά δεδομένα μπορεί να οδηγήσει σε ασυνεπή εκτέλεση Το πρόβλημα του κρίσιμου τμήματος (critical section): το πολύ μία διεργασία πρέπει να βρίσκεται στο κρίσιμο τμήμα σε κάθε χρονική στιγμή Δεν μας ενδιαφέρει η σειρά εκτέλεσης, αλλά η συντονισμένη πρόσβαση στα κοινά δεδομένα Η σωστή παράλληλη εκτέλεση απαιτεί συγκεκριμένη σειρά εκτέλεσης, όπως π.χ. επιβάλλεται από το γράφο των εξαρτήσεων Το πρόβλημα της σειριοποίησης (ordering) Υπάρχει αυστηρά προκαθορισμένη σειρά με την οποία πρέπει να εκτελεστούν οι εργασίες
4 Άλλα patterns συγχρονισμού Φράγμα συγχρονισμού (barrier) Όλες οι διεργασίες που συμμετέχουν συγχρονίζονται σε ένα συγκεκριμένο σημείο κώδικα Ειδική περίπτωση της σειριοποίησης Αναγνώστες-εγγραφείς (readers writers) Στο «κρίσιμο τμήμα» επιτρέπεται να είναι είτε: Καμία διεργασία Οσεσδήποτε διεργασίες αναγνώστες Μία διεργασία εγγραφέας Παραγωγός-καταναλωτής (producer consumer) Φραγμένος αριθμός από προϊόντα (0 < items < N) Ο παραγωγός εισέρχεται στο «κρίσιμο τμήμα» όταν items < N Ο καταναλωτής εισέρχεται στο «κρίσιμο τμήμα» όταν items > 0 Χρειάζεται συγχρονισμένη πρόσβαση στη δομή που κρατάει τα προϊόντα και συγχρονισμένη ενημέρωση του μετρητή items 4
5 Μηχανισμοί συγχρονισμού Κλειδώματα (locks) Προστατεύει ένα τμήμα κώδικα από ταυτόχρονη πρόσβαση Μόνο η διεργασία που έχει λάβει το κλείδωμα μπορεί να προχωρήσει Σημαφόροι (semaphores) Ακέραιος αριθμός στον οποίο επιτρέπονται 3 ενέργειες Αρχικοποίηση Αύξηση της τιμής κατά 1 Μείωση της τιμής κατά 1 και μπλοκάρισμα αν η νέα τιμή είναι 0 (ή αρνητική ανάλογα με την υλοποίηση) Παρακολουθητές (monitors) και μεταβλητές συνθήκης (condition variables) Ζεύγος κλειδώματος και condition variable (m, c) Μία διεργασία αναστέλλει τη λειτουργία της (λειτουργία wait) μέχρι να ισχύσει η κατάλληλη συνθήκη Μία διεργασία «ξυπνάει» (λειτουργία signal) κάποια από (ή όλες) τις διεργασίες που περιμένουν 5
6 Το πρόβλημα του κρίσιμου τμήματος (και οι ιδιότητές του) 1. Αμοιβαίος αποκλεισμός (mutual exclusion) 2. Πρόοδος (deadlock free) 3. Πεπερασμένη αναμονή (starvation free) Τα 1 και 2 είναι αναγκαία, το 3 επιθυμητό
7 Το κλείδωμα ως λύση του κρίσιμου τμήματος do { lock(mylock); /* critical section */ code unlock(mylock); remainder section while (TRUE); do { lock(mylock); /* critical section */ other code unlock(mylock); other remainder section while (TRUE);
8 Το κλείδωμα ως λύση του κρίσιμου τμήματος do { lock(mylock); /* critical section */ code unlock(mylock); remainder section while (TRUE); do { lock(mylock); /* critical section */ other code unlock(mylock); other remainder section while (TRUE); Πώς υλοποιείται ένα σωστό και «καλό» κλείδωμα;
9 Λύση στο λογισμικό: Peterson s lock δουλεύει για 2 νήματα // i = εγώ // j = το άλλο νήμα public void lock() { flag[i] = true; victim = i; while (flag[j] && victim == i) {; public void unlock() { flag[i] = false;
10 Λύση στο λογισμικό: Peterson s lock δουλεύει για 2 νήματα // i = εγώ «Θέλω να μπω» // j = το άλλο νήμα public void lock() { flag[i] = true; victim = i; while (flag[j] && victim == i) {; public void unlock() { flag[i] = false;
11 Λύση στο λογισμικό: Peterson s lock δουλεύει για 2 νήματα // i = εγώ «Θέλω να μπω» // j = το άλλο νήμα public void lock() { flag[i] = true; victim = i; while (flag[j] && victim == i) {; public void unlock() { flag[i] = false; Παραχώρηση προτεραιότητας «Μπες εσύ»
12 Λύση στο λογισμικό: Peterson s lock δουλεύει για 2 νήματα // i = εγώ // j = το άλλο νήμα public void lock() { flag[i] = true; victim = i; while (flag[j] && victim == i) {; public void unlock() { flag[i] = false; «Θέλω να μπω» Παραχώρηση προτεραιότητας «Μπες εσύ» Αν το άλλο νήμα θέλει να μπει και έχει προτεραιότητα περιμένω, αλλιώς μπαίνω στο κρίσιμο τμήμα
13 χρόνος Λύση στο λογισμικό: Peterson s lock δουλεύει για 2 νήματα Νήμα 1 Νήμα 2 «Θέλω να μπω» «Θέλω να μπω» «Μπες εσύ» «Μπες εσύ» Αν το άλλο νήμα θέλει να μπει και έχει προτεραιότητα περιμένω, αλλιώς μπαίνω στο κρίσιμο τμήμα Αν το άλλο νήμα θέλει να μπει και έχει προτεραιότητα περιμένω, αλλιώς μπαίνω στο κρίσιμο τμήμα
14 χρόνος Λύση στο λογισμικό: Peterson s lock δουλεύει για 2 νήματα Νήμα 1 Νήμα 2 «Θέλω να μπω» «Θέλω να μπω» «Μπες εσύ» «Μπες εσύ» Αν το άλλο νήμα θέλει να μπει και έχει προτεραιότητα περιμένω, αλλιώς μπαίνω στο κρίσιμο τμήμα Μπαίνει στο κρίσιμο τμήμα Αν το άλλο νήμα θέλει να μπει και έχει προτεραιότητα περιμένω, αλλιώς μπαίνω στο κρίσιμο τμήμα Μπλοκάρει
15 χρόνος Λύση στο λογισμικό: Peterson s lock δουλεύει για 2 νήματα Νήμα 1 Νήμα 2 «Θέλω να μπω» «Θέλω να μπω» «Μπες εσύ» «Μπες εσύ» Αν το άλλο νήμα θέλει να μπει και έχει προτεραιότητα περιμένω, αλλιώς μπαίνω στο κρίσιμο τμήμα Αν ο compiler ή ο επεξεργαστής αναδιατάξει την 1 η εντολή: Αν το άλλο νήμα θέλει να μπει και έχει προτεραιότητα περιμένω, αλλιώς μπαίνω στο κρίσιμο τμήμα
16 χρόνος Λύση στο λογισμικό: Peterson s lock δουλεύει για 2 νήματα Νήμα 1 Νήμα 2 «Θέλω να μπω» «Θέλω να μπω» «Μπες εσύ» «Μπες εσύ» Αν το άλλο νήμα θέλει να μπει και έχει προτεραιότητα περιμένω, αλλιώς μπαίνω στο κρίσιμο τμήμα Αν το άλλο νήμα θέλει να μπει και έχει προτεραιότητα περιμένω, αλλιώς μπαίνω στο κρίσιμο τμήμα
17 χρόνος Λύση στο λογισμικό: Peterson s lock δουλεύει για 2 νήματα Νήμα 1 Νήμα 2 «Μπες εσύ» «Θέλω να μπω» «Μπες εσύ» Αν το άλλο νήμα θέλει να μπει και έχει προτεραιότητα περιμένω, αλλιώς μπαίνω στο κρίσιμο τμήμα Αν το άλλο νήμα θέλει να μπει και έχει προτεραιότητα περιμένω, αλλιώς μπαίνω στο κρίσιμο τμήμα «Θέλω να μπω»
18 χρόνος Λύση στο λογισμικό: Peterson s lock δουλεύει για 2 νήματα Νήμα 1 Νήμα 2 «Μπες εσύ» «Θέλω να μπω» «Μπες εσύ» Αν το άλλο νήμα θέλει να μπει και έχει προτεραιότητα περιμένω, αλλιώς μπαίνω στο κρίσιμο τμήμα Μπαίνει στο κρίσιμο τμήμα «Θέλω να μπω» Αν το άλλο νήμα θέλει να μπει και έχει προτεραιότητα περιμένω, αλλιώς μπαίνω στο κρίσιμο τμήμα Μπαίνει στο κρίσιμο τμήμα
19 class Bakery { boolean[] flag; Label[] label; int size; Λύση στο λογισμικό: Lamport s Bakery Algorithm public Bakery (int n) { flag = new boolean[n]; label = new Label[n]; for (int i = 0; i < n; i++) { flag[i] = false; label[i] = 0; public void lock() { int i = ThreadID.get(); flag[i] = true; label[i] = max(label[0],, label[n-1]) + 1; while ((Эk!= i)(flag[k] && (label[k],k) << label[i],i))) {; public void unlock() { flag[threadid.get()] = false;
20 class Bakery { boolean[] flag; Label[] label; int size; Λύση στο λογισμικό: Lamport s Bakery Algorithm «Θέλω να μπω» public Bakery (int n) { flag = new boolean[n]; label = new Label[n]; for (int i = 0; i < n; i++) { flag[i] = false; label[i] = 0; public void lock() { int i = ThreadID.get(); flag[i] = true; label[i] = max(label[0],, label[n-1]) + 1; while ((Эk!= i)(flag[k] && (label[k],k) << label[i],i))) {; public void unlock() { flag[threadid.get()] = false;
21 class Bakery { boolean[] flag; Label[] label; int size; public Bakery (int n) { flag = new boolean[n]; label = new Label[n]; for (int i = 0; i < n; i++) { flag[i] = false; label[i] = 0; Λύση στο λογισμικό: Lamport s Bakery Algorithm «Θέλω να μπω» Παίρνει σειρά προτεραιότητας public void lock() { int i = ThreadID.get(); flag[i] = true; label[i] = max(label[0],, label[n-1]) + 1; while ((Эk!= i)(flag[k] && (label[k],k) << label[i],i))) {; public void unlock() { flag[threadid.get()] = false;
22 class Bakery { boolean[] flag; Label[] label; int size; Λύση στο λογισμικό: Lamport s Bakery Algorithm «Θέλω να μπω» public Bakery (int n) { flag = new boolean[n]; label = new Label[n]; for (int i = 0; i < n; i++) { flag[i] = false; label[i] = 0; public void lock() { int i = ThreadID.get(); flag[i] = true; label[i] = max(label[0],, label[n-1]) + 1; while ((Эk!= i)(flag[k] && (label[k],k) << label[i],i))) {; public void unlock() { flag[threadid.get()] = false; Παίρνει σειρά προτεραιότητας Αναμονή μέχρι να έρθει η προτεραιότητά μου Αν 2 νήματα έχουν αποκτήσει τον ίδιο αριθμό προτεραιότητας, λαμβάνεται υπόψη το id τους
23 class Bakery { boolean[] flag; Label[] label; int size; Λύση στο λογισμικό: Lamport s Bakery Algorithm public Bakery (int n) { flag = new boolean[n]; label = new Label[n]; for (int i = 0; i < n; i++) { flag[i] = false; label[i] = 0; public void lock() { int i = ThreadID.get(); flag[i] = true; label[i] = max(label[0],, label[n-1]) + 1; while ((Эk!= i)(flag[k] && (label[k],k) << label[i],i))) {; «Δεν θέλω να μπω» public void unlock() { flag[threadid.get()] = false;
24 Ζητήματα λύσεων στο λογισμικό Βασίζονται σε απλές αναγνώσεις και εγγραφές στη μνήμη (+) Το κλείδωμα του Peterson: Λειτουργεί μόνο για 2 διεργασίες (-) To κλείδωμα του Lamport Λειτουργεί για Ν διεργασίες (+) Διατρέχει Ν θέσεις μνήμης και αυτό μπορεί να είναι πολύ αργό και μη κλιμακώσιμο για μεγάλα Ν (-) Και τα 2 κλειδώματα δεν λειτουργούν αν ο μεταγλωττιστής ή ο επεξεργαστής αναδιατάξουν εντολές (υποθέτουν ότι το σύστημα υλοποιεί ακολουθιακή συνέπεια sequential consistency) (-) Στο μεταγλωττιστή μπορώ να το επιβάλλω Στον επεξεργαστή χρειάζεται ειδική υποστήριξη 24
25 Ακολουθιακή συνέπεια (sequential consistency) Ένας πολυεπεξεργαστής είναι ακολουθιακά συνεπής αν το αποτέλεσμα οποιασδήποτε εκτέλεσης είναι το ίδιο ως εάν οι εντολές όλων των επιμέρους επεξεργαστών εκτελούνταν σειριακά και οι εντολές του κάθε επιμέρους επεξεργαστή εκτελούνται με τη σειρά που ορίζεται στο πρόγραμμα (Lamport, 1979). 25
26 Ακολουθιακή συνέπεια (sequential consistency) Ένας πολυεπεξεργαστής είναι ακολουθιακά συνεπής αν το αποτέλεσμα οποιασδήποτε εκτέλεσης είναι το ίδιο ως εάν οι εντολές όλων των επιμέρους επεξεργαστών εκτελούνταν σειριακά και οι εντολές του κάθε επιμέρους επεξεργαστή εκτελούνται με τη σειρά που ορίζεται στο πρόγραμμα (Lamport, 1979). Ικανές συνθήκες: Κάθε διεργασία εκκινεί εντολές πρόσβασης στη μνήμη με τη σειρά που ορίζεται στο πρόγραμμα W R R Μετά την εκκίνηση μιας εντολής εγγραφής στη μνήμη ο εκτελών επεξεργαστής περιμένει μέχρι η εγγραφή να ολοκληρωθεί πριν εκτελέσει την επόμενη εντολή W R R Μετά την εκκίνηση μιας εντολής ανάγνωσης, ο εκτελών επεξεργαστής πρέπει να περιμένει την ολοκλήρωση της εντολής ανάγνωσης αλλά και την ολοκλήρωση της εντολής εγγραφής στη θέση μνήμης στην οποία γίνεται η ανάγνωση W (8) R (8) R 26
27 Ακολουθιακή συνέπεια (sequential consistency) Ένας πολυεπεξεργαστής είναι ακολουθιακά συνεπής αν το αποτέλεσμα οποιασδήποτε εκτέλεσης είναι το ίδιο ως εάν οι εντολές όλων των επιμέρους επεξεργαστών εκτελούνταν σειριακά και οι εντολές του κάθε επιμέρους επεξεργαστή εκτελούνται με τη σειρά που ορίζεται στο πρόγραμμα (Lamport, 1979). Ικανές συνθήκες: Κάθε διεργασία εκκινεί εντολές πρόσβασης στη μνήμη με τη σειρά που ορίζεται στο πρόγραμμα (περιορισμός out-of-order execution) Μετά την εκκίνηση μιας εντολής εγγραφής στη μνήμη ο εκτελών επεξεργαστής περιμένει μέχρι η εγγραφή να ολοκληρωθεί πριν εκτελέσει την επόμενη εντολή (επιπλέον σειριοποίηση) Μετά την εκκίνηση μιας εντολής ανάγνωσης, ο εκτελών επεξεργαστής πρέπει να περιμένει την ολοκλήρωση της εντολής ανάγνωσης αλλά και την ολοκλήρωση της εντολής εγγραφή στη θέση μνήμης στην οποία γίνεται η ανάγνωση (επιπλέον σειριοποίηση και καθολική λειτουργία) 27
28 Ακολουθιακή συνέπεια (sequential consistency) Ένας πολυεπεξεργαστής είναι ακολουθιακά συνεπής αν το αποτέλεσμα οποιασδήποτε εκτέλεσης είναι το ίδιο ως εάν οι εντολές όλων των επιμέρους επεξεργαστών εκτελούνταν σειριακά και οι εντολές του κάθε επιμέρους επεξεργαστή εκτελούνται με τη σειρά που ορίζεται στο πρόγραμμα (Lamport, 1979). Η σειρά που ορίζεται στο πρόγραμμα είναι η σειρά που έχει παράξει ο μεταγλωττιστής. Ποιος εγγυάται ότι ο μεταγλωττιστής δεν έχει αναδιατάξει εντολές; Προσοχή: Οι παραπάνω αλγόριθμοι στο λογισμικό είναι κατανεμημένοι, δηλαδή οι εγγραφές σε έναν επεξεργαστή επηρεάζουν την ορθή εκτέλεση σε έναν άλλο επεξεργαστή. Αυτή η σημασιολογία όμως δεν είναι γνωστή ούτε στον επεξεργαστή, ούτε στο μεταγλωττιστή που με βάση την τοπική ανάλυση εξαρτήσεων έχουν τη δυνατότητα να κάνουν αναδιατάξεις για λόγους βελτιστοποίησης 28
29 Μοντέλα μνήμης Η ακολουθιακή συνέπεια μπορεί να υποστηρίξει κατανεμημένους αλγορίθμους συγχρονισμού στο λογισμικό Έχει όμως πολύ μεγάλο κόστος στην επίδοση Γιατί να το πληρώσουν και τα σειριακά προγράμματα ή τα προγράμματα που δεν συγχρονίζονται; Λύση: Ο προγραμματιστής θα πρέπει να αναλάβει να επισημαίνει τα σημεία όπου χρειάζεται συγχρονισμός (release consistency) Ο μεταγλωττιστής και ο επεξεργαστής κάνουν βελτιστοποιήσεις ανάμεσα στις περιοχές όπου επισημαίνονται με «φράγματα συγχρονισμού» Οι παράλληλες γλώσσες προγραμματισμού και οι επεξεργαστές ορίζουν «μοντέλα μνήμης», δηλαδή τις επιτρεπτές αναδιατάξεις στις εντολές πρόσβασης στη μνήμη 29
30 Υποστήριξη από το υλικό: atomic operations, π.χ. test-and-set, compare-and-swap Ατομικά ενεργούν σε 2 μεταβλητές Στις υλοποιήσεις τους τυπικά περιλαμβάνουν και memory fence (επιβολή για ολοκλήρωση όλων των προηγούμενων εντολών πρόσβασης στη μνήμη) 0 State Test (0 = unlocked 1 = locked)
31 Υποστήριξη από το υλικό: atomic operations, π.χ. test-and-set, compare-and-swap Ατομικά ενεργούν σε 2 μεταβλητές Στις υλοποιήσεις τους τυπικά περιλαμβάνουν και memory fence (επιβολή για ολοκλήρωση όλων των προηγούμενων εντολών πρόσβασης στη μνήμη) State Test (0 = unlocked 1 = locked)
32 Υποστήριξη από το υλικό: atomic operations, π.χ. test-and-set, compare-and-swap Ατομικά ενεργούν σε 2 μεταβλητές Στις υλοποιήσεις τους τυπικά περιλαμβάνουν και memory fence (επιβολή για ολοκλήρωση όλων των προηγούμενων εντολών πρόσβασης στη μνήμη) 1 Με ένα ατομικό operation θέτω το lock (State=1) και «βλέπω» την προηγούμενη κατάσταση (στη μεταβλητή Test) State Test (0 = unlocked 1 = locked)
33 Υποστήριξη από το υλικό: atomic operations, π.χ. test-and-set, compare-and-swap Ατομικά ενεργούν σε 2 μεταβλητές Στις υλοποιήσεις τους τυπικά περιλαμβάνουν και memory fence (επιβολή για ολοκλήρωση όλων των προηγούμενων εντολών πρόσβασης στη μνήμη) 1 Με ένα ατομικό operation θέτω το lock (State=1) και «βλέπω» την προηγούμενη κατάσταση (στη μεταβλητή Test) State (0 = unlocked 1 = locked) Test Αν test = 0 (ήταν «ξεκλείδωτα») μπαίνω στο critical section, αλλιώς περιμένω
34 Test-and-set (TAS) lock class TASlock { AtomicBoolean state = new AtomicBoolean(false); void lock() { while (state.getandset(true)) { void unlock() { state.set(false);
35 TAS lock in a bus-based multiprocessor Thread 1 inside critical section CPU0 CPU1 CPU2 Memory state test cache 1 0 cache cache state test 1 0 bus
36 TAS lock in a bus-based multiprocessor Thread 1 inside critical section CPU0 Thread 2 tries to enter critical section CPU1 while (state.getandset(true)) { Thread 3 tries to enter critical section CPU2 while (state.getandset(true)) { Memory state test cache 1 0 cache cache state test 1 0 bus
37 TAS lock in a bus-based multiprocessor Thread 1 inside critical section CPU0 Thread 2 tries to enter critical section CPU1 while (state.getandset(true)) { Thread 3 tries to enter critical section CPU2 while (state.getandset(true)) { Memory state test cache 1 1 state test cache 1 1 state test cache 1 1 state test 1 1 bus
38 TAS lock in a bus-based multiprocessor Thread 1 inside critical section CPU0 Thread 2 tries to enter critical section CPU1 while (state.getandset(true)) { Thread 3 tries to enter critical section CPU2 while (state.getandset(true)) { Memory state test cache 1 1 state test cache 1 1 state test cache 1 1 state test 1 1 bus Υπερβολική χρήση του διαδρόμου λόγω πρωτοκόλλου συνάφειας κρυφής μνήμης
39 Test and test and set (TTAS) lock class TTASlock { AtomicBoolean state = new AtomicBoolean(false); void lock() { while (true) { while (state.get()) {; if (!state.getandset(true)) return; void unlock() { state.set(false);
40 Test and test and set (TTAS) lock class TTASlock { AtomicBoolean state = new AtomicBoolean(false); «Επίμονο» διάβασμα της void lock() { κατάστασης του lock while (true) { while (state.get()) {; if (!state.getandset(true)) return; void unlock() { state.set(false);
41 Test and test and set (TTAS) lock class TTASlock { AtomicBoolean state = new AtomicBoolean(false); «Επίμονο» διάβασμα της κατάστασης του lock void lock() { while (true) { while (state.get()) {; if (!state.getandset(true)) return; void unlock() { state.set(false); Αν είναι «ξεκλείδωτο» το διεκδικώ
42 time Επίδοση TAS vs TTAS TAS lock TTAS lock Ideal threads
43 time Επίδοση TAS vs TTAS TAS lock TTAS lock Ideal threads Περαιτέρω βελτίωση: TTAS + εκθετική οπισθοχώρηση (exponential backoff)
44 Scalable locks Σε ένα σύστημα κοινής μνήμης δεν είναι καλή ιδέα πολλά threads να «συνωστίζονται» σε μία κοινή θέση μνήμης Δημιουργείται μεγάλη κυκλοφορία δεδομένων από το σύστημα συνάφειας κρυφής μνήμης Προτιμούμε τα νήματα να εργάζονται το καθένα στο δικό του χώρο και να έχουν πρόσβαση σε κοινές θέσεις σπάνια και με λογική point-to-point, π.χ. 2 [Ο(1)] νήματα ανά θέση μνήμης
45 Queue Locks: Array-based lock class ALock { ThreadLocal<Integer> myslotindex; boolean[] flag; AtomicInteger tail; int size; public Alock (int capacity) { size = capacity; flag = new boolean[capacity]; flag[0] = true; tail = new AtomicInteger(0); public void lock() { int slot = tail.getandincrement() % size; myslotindex.set(slot); while (!flag[slot]){; public void unlock() { int slot = myslotindex.get(); flag[slot] = false; flag[(slot + 1) % size] = true;
46 Queue Locks: Array-based lock class ALock { ThreadLocal<Integer> myslotindex; boolean[] flag; AtomicInteger tail; int size; public Alock (int capacity) { size = capacity; flag = new boolean[capacity]; flag[0] = true; tail = new AtomicInteger(0); Τοπική μεταβλητή ανά thread Πίνακας-ουρά με αριθμό θέσεων ίσο με τον αριθμό των threads Δείκτης στο τέλος της ουράς public void lock() { int slot = tail.getandincrement() % size; myslotindex.set(slot); while (!flag[slot]){; public void unlock() { int slot = myslotindex.get(); flag[slot] = false; flag[(slot + 1) % size] = true;
47 Queue Locks: Array-based lock class ALock { ThreadLocal<Integer> myslotindex; boolean[] flag; AtomicInteger tail; int size; public Alock (int capacity) { size = capacity; flag = new boolean[capacity]; flag[0] = true; tail = new AtomicInteger(0); public void lock() { int slot = tail.getandincrement() % size; myslotindex.set(slot); while (!flag[slot]){; public void unlock() { int slot = myslotindex.get(); flag[slot] = false; flag[(slot + 1) % size] = true; 6 5 false false 7 false false 4 tail 0 true false 3 0 false false 2 Alock mylock = new Alock(8); /* Thread code */ mylock.lock(); /* critical section */ mylock.unlock(); 1
48 Queue Locks: Array-based lock class ALock { ThreadLocal<Integer> myslotindex; boolean[] flag; AtomicInteger tail; int size; public Alock (int capacity) { size = capacity; flag = new boolean[capacity]; flag[0] = true; tail = new AtomicInteger(0); 6 5 false false 7 false false 4 tail 1 0 true false 3 1 false false 2 Thread A mylock.lock() public void lock() { int slot = tail.getandincrement() % size; myslotindex.set(slot); while (!flag[slot]){; public void unlock() { int slot = myslotindex.get(); flag[slot] = false; flag[(slot + 1) % size] = true;
49 Queue Locks: Array-based lock class ALock { ThreadLocal<Integer> myslotindex; boolean[] flag; AtomicInteger tail; int size; public Alock (int capacity) { size = capacity; flag = new boolean[capacity]; flag[0] = true; tail = new AtomicInteger(0); 6 5 false false 7 false false 4 tail 2 0 true false 3 1 false false 2 Thread A in CS Thread B mylock.lock() public void lock() { int slot = tail.getandincrement() % size; myslotindex.set(slot); while (!flag[slot]){; public void unlock() { int slot = myslotindex.get(); flag[slot] = false; flag[(slot + 1) % size] = true;
50 Queue Locks: Array-based lock class ALock { ThreadLocal<Integer> myslotindex; boolean[] flag; AtomicInteger tail; int size; public Alock (int capacity) { size = capacity; flag = new boolean[capacity]; flag[0] = true; tail = new AtomicInteger(0); 6 5 false false 7 false false 4 tail 3 0 true false 3 1 false false 2 Thread A in CS Thread B mylock.lock() Thread C mylock.lock() public void lock() { int slot = tail.getandincrement() % size; myslotindex.set(slot); while (!flag[slot]){; public void unlock() { int slot = myslotindex.get(); flag[slot] = false; flag[(slot + 1) % size] = true;
51 Queue Locks: Array-based lock class ALock { ThreadLocal<Integer> myslotindex; boolean[] flag; AtomicInteger tail; int size; public Alock (int capacity) { size = capacity; flag = new boolean[capacity]; flag[0] = true; tail = new AtomicInteger(0); 6 5 false false 7 false false 4 tail 3 0 false false 3 1 true false 2 Thread A mylock.unlock() Thread B mylock.lock() Thread C mylock.lock() public void lock() { int slot = tail.getandincrement() % size; myslotindex.set(slot); while (!flag[slot]){; public void unlock() { int slot = myslotindex.get(); flag[slot] = false; flag[(slot + 1) % size] = true;
52 Queue Locks: Array-based lock class ALock { ThreadLocal<Integer> myslotindex; boolean[] flag; AtomicInteger tail; int size; public Alock (int capacity) { size = capacity; flag = new boolean[capacity]; flag[0] = true; tail = new AtomicInteger(0); 6 5 false false 7 false false 4 tail 3 0 false false 3 1 true false 2 Thread B In CS Thread C mylock.lock() public void lock() { int slot = tail.getandincrement() % size; myslotindex.set(slot); while (!flag[slot]){; public void unlock() { int slot = myslotindex.get(); flag[slot] = false; flag[(slot + 1) % size] = true;
53 Επισημάνσεις Η επίδοση κάθε μηχανισμού κλειδώματος εξαρτάται από τη συμφόρηση Αριθμός νημάτων Μέγεθος κρίσιμου τμήματος Μέγεθος μη-κρίσιμου τμήματος Δεν υπάρχει ένα κλείδωμα για όλες τις περιπτώσεις Υβριδικές προσεγγίσεις έχουν νόημα Οι παραπάνω υλοποιήσεις αφορούν spinlocks ο επεξεργαστής είναι κατειλημμένος όσο ένα νήμα επιχειρεί να εισέλθει στο κρίσιμο τμήμα Μπορούν να συνδυαστούν ορθογώνια με προσεγγίσεις όπου το νήμα απελευθερώνει τον επεξεργαστή μετά από κάποιο χρονικό διάστημα 53
54 Monitors και Condition Variables Η ορθή υλοποίηση σύνθετων προγραμμάτων με τη χρήση κλειδωμάτων είναι δύσκολη και συχνά οδηγεί σε σφάλματα Είναι επιθυμητό να αναθέτουμε μέρος της υλοποίησης του συγχρονισμού σε κάποια βιβλιοθήκη ή στον compiler Ο πραγματικός σχεδιασμός και ο εντοπισμός των αναγκών του συγχρονισμού παραμένει Ο προγραμματιστής προτιμά να περιγράφει το «τι» και όχι το «πως» 54
55 Monitors Τα monitors (παρακολουθητές) είναι δομές συγχρονισμού υψηλού επιπέδου Υποστηρίζουν: Ατομική εκτέλεση των μεθόδων που ορίζονται εντός ενός monitor (η κατάλληλη χρήση των κλειδωμάτων για το σκοπό αυτό γίνεται από τον compiler αυτόματα) Αναμονή ενός νήματος μέχρι να ικανοποιηθεί κάποια συνθήκη με τη χρήση condition variables 55
56 Condition variables Εξομοιώνουν μία αίθουσα αναμονής στην οποία εισέρχονται νήματα μέχρι να ικανοποιηθεί μία συνθήκη (π.χ. να απελευθερωθεί χώρος σε μία γεμάτη ουρά) Υποστηρίζουν λειτουργίες αναστολής λειτουργίας (wait) ενός νήματος αν δεν ισχύει μία συνθήκη και ειδοποίησης των νημάτων σε αναμονή (signal) όταν ισχύει η συνθήκη Τυπικά εμπλέκουν το λειτουργικό σύστημα για την αναστολή λειτουργίας και την ενημέρωση Συνδέονται με ένα κλείδωμα Ο έλεγχος της συνθήκης γίνεται υπό την κατοχή κλειδώματος Η αναστολή λειτουργίας έπεται της απελευθέρωσης του κλειδώματος Η ανάνηψη από την αναμονή έπεται της επανάκτησης του κλειδώματος 56
57 Condition variables: Τρόπος λειτουργίας 57
58 Condition variables - διεπαφή public interface Lock { void lock(); void lockinterruptibly() throws InterruptedException; boolean trylock(); boolean trylock(long time, TimeUnit unit); Condition newcondition(); void unlock(); public interface Condition { void await() throws InterruptedException; boolean await(long time, TimeUnit unit) throws InterruptedException; boolean awaituntil(date deadline) throws InterruptedException; long awaitnanos(long nanostimeout) throws InterruptedException; void awaituninterruptibly(); void signal(); // wake up one waiting thread void signalall(); // wake up all waiting threads 58
59 class Queue<T> { final Lock lock = new ReentrantLock(); final Condition notfull = lock.newcondition(); final Condition notempty = lock.newcondition(); final T[] items; int tail, head, count; public Queue(int capacity) { items = (T[])new Object[capacity]; public void enq(t x) throws InterruptedException { lock.lock(); try { while (count == items.length) notfull.await(); items[tail] = x; if (++tail == items.length) tail = 0; ++count; notempty.signal(); finally { lock.unlock(); LockedQueue enq() Λήψη lock 59
60 class Queue<T> { final Lock lock = new ReentrantLock(); final Condition notfull = lock.newcondition(); final Condition notempty = lock.newcondition(); final T[] items; int tail, head, count; public Queue(int capacity) { items = (T[])new Object[capacity]; public void enq(t x) throws InterruptedException { lock.lock(); try { while (count == items.length) notfull.await(); items[tail] = x; if (++tail == items.length) tail = 0; ++count; notempty.signal(); finally { lock.unlock(); LockedQueue enq() Έλεγχος συνθήκης και αναστολή λειτουργίας. Απελευθέρωση του lock εντός της await() 60
61 class Queue<T> { final Lock lock = new ReentrantLock(); final Condition notfull = lock.newcondition(); final Condition notempty = lock.newcondition(); final T[] items; int tail, head, count; public Queue(int capacity) { items = (T[])new Object[capacity]; public void enq(t x) throws InterruptedException { lock.lock(); try { while (count == items.length) notfull.await(); items[tail] = x; if (++tail == items.length) tail = 0; ++count; notempty.signal(); finally { lock.unlock(); LockedQueue enq() Εισαγωγή στοιχείου στην ουρά. Αν η διεργασία έχει μόλις ξυπνήσει βρίσκεται με το lock σε κατοχή 61
62 class Queue<T> { final Lock lock = new ReentrantLock(); final Condition notfull = lock.newcondition(); final Condition notempty = lock.newcondition(); final T[] items; int tail, head, count; public Queue(int capacity) { items = (T[])new Object[capacity]; public void enq(t x) throws InterruptedException { lock.lock(); try { while (count == items.length) notfull.await(); items[tail] = x; if (++tail == items.length) tail = 0; ++count; notempty.signal(); finally { lock.unlock(); LockedQueue enq() Ειδοποίηση σε κάθε περίπτωση 62
63 class Queue<T> { final Lock lock = new ReentrantLock(); final Condition notfull = lock.newcondition(); final Condition notempty = lock.newcondition(); final T[] items; int tail, head, count; public Queue(int capacity) { 63 items = (T[])new Object[capacity]; public T deq() throws InterruptedException { lock.lock(); try { while (count == 0) notempty.await(); T x = items[head]; if (++head == items.length) head = 0; --count; notfull.signal(); return x; finally { lock.unlock(); LockedQueue deq() Ανάλογα για το enq()
64 The lost wakeup problem Εμφανής βελτιστοποίηση στην υλοποίηση της προηγούμενης ουράς: Ειδοποίηση των νημάτων υπό αναμονή μόνο στις οριακές καταστάσεις (εισαγωγή 1 ου item στην ουρά, διαγραφή από πλήρη λίστα) Σε αυτή την περίπτωση μπορεί να υπάρξει η παρακάτω ακολουθία λειτουργιών σε άδεια ουρά: 1. Consumer A.deq() // κοιμάται 2. Consumer B.deq() // κοιμάται 3. Producer C.enq() // items == 1 4. Producer C.signal() 5. Consumer A: ξυπνά αλλά δεν προλαβαίνει να πάρει το lock 6. Producer D enq() // items = 2 (δεν κάνει signal γιατί δε βρήκε άδεια ουρά) 7. Consumer A: παίρνει το lock και καταναλώνει ένα αντικείμενο //items = 1 Λύση: Ο Consumer B δεν ξυπνά ποτέ παρόλο που υπάρχει αντικείμενο να καταναλώσει! Ενημερώνουμε (ξυπνάμε) όλα τα νήματα σε αναμονή (signalall) Ορίζουμε timeout στην αναμονή 64
65 Τακτικές συγχρονισμού για δομές δεδομένων (1) Coarse-grain synchronization Χρησιμοποιείται ένα κλείδωμα για όλη τη δομή Εύκολη υλοποίηση Περιορίζει την παράλληλη πρόσβαση των νημάτων στη δομή Fine-grain synchronization Χρησιμοποιούνται περισσότερα κλειδώματα σε τμήματα της δομής Εξασφαλίζεται παράλληλη πρόσβαση στη δομή από πολλαπλά νήματα Δύσκολη υλοποίηση Υψηλό κόστος κτήσης / απελευθέρωσης κλειδωμάτων Optimistic synchronization Για εισαγωγή/διαγραφή: αναζήτηση του στοιχείου χωρίς κλείδωμα Αν βρεθεί: χρησιμοποιείται κλείδωμα γίνεται έλεγχος αν το στοιχείο εξακολουθεί να είναι στη δομή πραγματοποιείται η επεξεργασία του στοιχείου Αναζήτηση: χρήση κλειδωμάτων
66 Τακτικές συγχρονισμού για δομές δεδομένων (2) Lazy synchronization Η διαδικασία διαιρείται σε 2 μέρη (ελαφρύ, βαρύ) Το ελαφρύ μέρος (π.χ. η λογική αφαίρεση ενός κόμβου μέσω της εγγραφής ενός tag) πραγματοποιείται αμέσως και με συγχρονισμό Το βαρύ μέρος (π.χ. η φυσική αφαίρεση ενός κόμβου διόρθωση των δεικτών) μπορεί να γίνει χωρίς συγχρονισμό αργότερα (lazy) Non-blocking synchronization Σε κάποιες περιπτώσεις μπορούμε να αποφύγουμε τα κλειδώματα Χρησιμοποιούνται οι ατομικές εντολές που παρέχει το υλικό (TAS, CAS) Transactional memory Προγραμματιστικό μοντέλο που υποστηρίζει ατομικές εκτελέσεις τμημάτων κώδικα (transactions) Τα transactions καταγράφονται Αν υπήρξε ταυτόχρονη πρόσβαση η εκτέλεση αναιρείται και επανεκκινείται Υλοποίηση σε λογισμικό (STM), υλικό (HTM) ή υβριδικά Επεξεργαστές: SUN Rock (canceled by Oracle), IBM BlueGene/Q, IBM zenterprise EC12, Intel Haswell/Broadwell, IBM Power
67 Σχήματα συγχρονισμού για συνδεδεμένες λίστες Δομή υπό εξέταση: Συνδεδεμένη λίστα με ταξινομημένα στοιχεία Κάθε κόμβος περιλαμβάνει: κλειδί - key (συνήθως hash key, ταξινομημένο) τιμή - value (τυπικά ένας δείκτης στο περιεχόμενο του κόμβου εδώ χρησιμοποιούμε έναν πραγματικό αριθμό για απλότητα) δείκτη στον επόμενο κόμβο Λειτουργίες: add (value), προστίθεται αν δεν υπάρχει remove (value), αφαιρείται αν υπάρχει contains (value), επιστρέφει true αν υπάρχει το κλειδί (υπάρχει μονοπάτι που καταλήγει στο κλειδί), αλλιώς false Περιλαμβάνει 2 κόμβους φρουρούς για την αρχή και το τέλος με τη μέγιστη και ελάχιστη τιμή Η δομή μπορεί να εμπλουτιστεί / τροποποιηθεί προκειμένου να υποστηρίξει κάποιο σχήμα συγχρονισμού
68 Συνδεδεμένες λίστες (λεπτομέρειες υλοποίησης) κλειδί key (ταξινομημένο) δείκτης - next στον επόμενο κόμβο τιμή value Κόμβοι φρουροί (sentinel nodes) με ελάχιστη και μέγιστη τιμή κλειδιού 68
69 Συνδεδεμένες λίστες (λεπτομέρειες υλοποίησης) public class Node { public T value; public int key; public Node next; 69
70 Συνδεδεμένες λίστες (προσθήκη στοιχείου)
71 Συνδεδεμένες λίστες (προσθήκη στοιχείου)
72 Συνδεδεμένες λίστες (αφαίρεση στοιχείου)
73 Συνδεδεμένες λίστες (αφαίρεση στοιχείου)
74 Coarse-grain synchronization Ένα κλείδωμα για όλη τη δομή 74
75 public class CoarseList<T> { private Node head; private Node tail; private Lock lock = new ReentrantLock(); Coarse-grain synchronization public CoarseList() { head = new Node(Integer.MIN_VALUE); tail = new Node(Integer.MAX_VALUE); head.next = this.tail; 75
76 public class CoarseList<T> { 76 public boolean add(t item) { Node pred, curr; int key = item.hashcode(); lock.lock(); try { pred = head; curr = pred.next; while (curr.key < key) { pred = curr; curr = curr.next; if (key == curr.key) { return false; else { Node node = new Node(item); node.next = curr; pred.next = node; return true; finally { lock.unlock(); Coarse-grain synchronization: add
77 public class CoarseList<T> { 77 public boolean add(t item) { Node pred, curr; int key = item.hashcode(); lock.lock(); try { pred = head; curr = pred.next; while (curr.key < key) { pred = curr; curr = curr.next; if (key == curr.key) { return false; else { Node node = new Node(item); node.next = curr; pred.next = node; return true; finally { lock.unlock(); Coarse-grain synchronization: add Ολόκληρη η εκτέλεση της μεθόδου περιλαμβάνεται σε ένα κρίσιμο τμήμα
78 public class CoarseList<T> { public boolean remove(t item) { Node pred, curr; int key = item.hashcode(); lock.lock(); try { pred = this.head; curr = pred.next; while (curr.key < key) { pred = curr; curr = curr.next; if (key == curr.key) { pred.next = curr.next; return true; else { return false; finally { lock.unlock(); Coarse-grain synchronization: remove Ολόκληρη η εκτέλεση της μεθόδου περιλαμβάνεται σε ένα κρίσιμο τμήμα Ομοίως και για τη μέθοδο contains Οι μέθοδοι διεκδικούν ένα κοινό lock άρα μόνο μία μπορεί να βρίσκεται σε εκτέλεση. Προφανής βελτίωση: readers-writers lock 78
79 Fine-grain synchronization Γιατί να κλειδώνουμε ολόκληρη τη δομή αν τα νήματα εργάζονται σε πλήρως ανεξάρτητα τμήματά της; Ιδέα: να χρησιμοποιήσουμε πολλαπλά κλειδώματα Τι ακριβώς πρέπει να κλειδώσουμε; 79
80 Fine-grain synchronization Πολλαπλά κλειδώματα για τη δομή 80
81 Αρκεί ένα κλείδωμα ανά κόμβο; Fine-grain synchronization Έστω ότι το νήμα Α θέλει να διαγράψει το 1 και το νήμα Β θέλει να διαγράψει το
82 Fine-grain synchronization Αρκεί ένα κλείδωμα ανά κόμβο; Νήμα Α
83 Fine-grain synchronization Αρκεί ένα κλείδωμα ανά κόμβο; Νήμα Α Νήμα Β
84 Fine-grain synchronization Αρκεί ένα κλείδωμα ανά κόμβο; Νήμα Α Νήμα Β
85 Fine-grain synchronization Αρκεί ένα κλείδωμα ανά κόμβο; Νήμα Α Νήμα Β Η δομή δεν είναι συνεπής! (το 4 δεν σβήστηκε) 85
86 Fine-grain synchronization Αρκεί ένα κλείδωμα ανά κόμβο; ΟΧΙ 86
87 Παρατήρηση: Fine-grain synchronization Αν ένας κόμβος είναι κλειδωμένος, κανείς δεν πρέπει να αφαιρεί τον επόμενό του το νήμα πρέπει να κλειδώνει τον προς αφαίρεση κόμβο και τον προηγούμενό του Αν πρόκειται να προστεθεί ένα κόμβος ανάμεσα σε δύο κόμβους, κανείς δεν πρέπει να προσθέσει κόμβο στο ίδιο σημείο το νήμα πρέπει να κλειδώνει τους κόμβους που βρίσκονται εκατέρωθεν αυτού που θα προστεθεί (τον αμέσως μικρότερο και τον αμέσως μεγαλύτερο) 87
88 Λύση: hand-over-hand locking Fine-grain synchronization Έστω ότι το νήμα Α θέλει να διαγράψει το 1 και το νήμα Β θέλει να διαγράψει το 4 Νήμα Α Νήμα Β
89 Λύση: hand-over-hand locking Fine-grain synchronization Έστω ότι το νήμα Α θέλει να διαγράψει το 1 και το νήμα Β θέλει να διαγράψει το 4 Νήμα Α Νήμα Β Μόνο ένα από τα νήματα θα πάρει το κλείδωμα για τον κόμβο 1 89
90 Fine-grain synchronization Διάσχιση λίστας
91 Fine-grain synchronization Διάσχιση λίστας
92 Fine-grain synchronization Διάσχιση λίστας
93 Fine-grain synchronization Διάσχιση λίστας
94 Fine-grain synchronization Διάσχιση λίστας
95 Fine-grain synchronization Διάσχιση λίστας
96 public boolean remove(t item) { Node pred, curr; int key = item.hashcode(); head.lock(); try { pred = head; curr = pred.next; curr.lock(); try { while (curr.key < key) { pred.unlock(); pred = curr; curr = curr.next; curr.lock(); if (curr.key == key) { pred.next = cur.next; return true; return false; finally { curr.unlock(); finally { pred.unlock(); Fine-grain synchronization: remove 96
97 public boolean remove(t item) { Node pred, curr; int key = item.hashcode(); head.lock(); try { pred = head; curr = pred.next; curr.lock(); try { while (curr.key < key) { pred.unlock(); pred = curr; curr = curr.next; curr.lock(); if (curr.key == key) { pred.next = cur.next; return true; return false; finally { curr.unlock(); finally { pred.unlock(); Fine-grain synchronization: remove Κλείδωμα της κεφαλής της λίστας 97
98 public boolean remove(t item) { Node pred, curr; int key = item.hashcode(); head.lock(); try { pred = head; curr = pred.next; curr.lock(); try { while (curr.key < key) { pred.unlock(); pred = curr; curr = curr.next; curr.lock(); if (curr.key == key) { pred.next = cur.next; return true; return false; finally { curr.unlock(); finally { pred.unlock(); Fine-grain synchronization: remove Πρόσβαση στην κεφαλή Πρόσβαση στο 2 ο στοιχείο Κλείδωμα 2 ου στοιχείου 98
99 public boolean remove(t item) { Node pred, curr; int key = item.hashcode(); head.lock(); try { pred = head; curr = pred.next; curr.lock(); try { while (curr.key < key) { pred.unlock(); pred = curr; curr = curr.next; curr.lock(); if (curr.key == key) { pred.next = cur.next; return true; return false; finally { curr.unlock(); finally { pred.unlock(); Fine-grain synchronization: remove Διασχίζεται η λίστα με hand-overhand locking 99
100 public boolean remove(t item) { Node pred, curr; int key = item.hashcode(); head.lock(); try { pred = head; curr = pred.next; curr.lock(); try { while (curr.key < key) { pred.unlock(); pred = curr; curr = curr.next; curr.lock(); if (curr.key == key) { pred.next = cur.next; return true; return false; finally { curr.unlock(); finally { pred.unlock(); Fine-grain synchronization: remove Διαγραφή στοιχείου ΣΗΜΕΙΩΣΗ: Στη συγκεκριμένη περίπτωση η φυσική διαγραφή του κόμβου πραγματοποιείται από το μηχανισμό garbage collection της γλώσσας 100
101 public boolean remove(t item) { Node pred, curr; int key = item.hashcode(); head.lock(); try { pred = head; curr = pred.next; curr.lock(); try { while (curr.key < key) { pred.unlock(); pred = curr; curr = curr.next; curr.lock(); if (curr.key == key) { pred.next = cur.next; return true; return false; finally { curr.unlock(); finally { pred.unlock(); Fine-grain synchronization: remove Απελευθέρωση κλειδωμάτων 101
102 public boolean remove(t item) { Node pred, curr; int key = item.hashcode(); head.lock(); try { pred = head; curr = pred.next; curr.lock(); try { while (curr.key < key) { pred.unlock(); pred = curr; curr = curr.next; curr.lock(); if (curr.key == key) { pred.next = cur.next; return true; return false; finally { curr.unlock(); finally { pred.unlock(); Fine-grain synchronization: remove Παρόμοια λογική για τις μεθόδους add και contains 102
103 Fine-grain synchronization Όλες οι μέθοδοι πρέπει να καταλαμβάνουν τα locks με την ίδια σειρά για να αποφευχθεί αδιέξοδο Έστω ότι το νήμα Α θέλει να προσθέσει το 2 και το νήμα Β να διαγράψει το 4 και το νήμα Α καταλαμβάνει locks από δεξιά προς τα αριστερά ενώ το νήμα Β από δεξιά προς τα αριστερά Νήμα Β Νήμα Α
104 Fine-grain synchronization Όλες οι μέθοδοι πρέπει να καταλαμβάνουν τα locks με την ίδια σειρά για να αποφευχθεί αδιέξοδο Έστω ότι το νήμα Α θέλει να προσθέσει το 2 και το νήμα Β να διαγράψει το 4 και το νήμα Α καταλαμβάνει locks από δεξιά προς τα αριστερά ενώ το νήμα Β από δεξιά προς τα αριστερά Νήμα Β Νήμα Α Αδιέξοδο: το ένα νήμα περιμένει να πάρει το lock που κρατά το άλλο 104
105 Optimistic synchronization O fine-grain συγχρονισμός αποτελεί βελτίωση σε σχέση με τον coarse-grain Παρόλα αυτά περιλαμβάνει μια μεγάλη σειρά από λήψεις και απελευθερώσεις κλειδωμάτων Νήματα που προσπελαύνουν διακριτά μέρη της λίστας μπορεί να αδυνατούν να εργαστούν ταυτόχρονα (π.χ. ένα νήμα που προσπελαύνει ένα στοιχείο στην αρχή της λίστας, εμποδίζει άλλα στοιχεία που θέλουν να προσπελάσουν τη μέση ή το τέλος της λίστας) Ας σκεφτούμε «αισιόδοξα», δηλαδή τα πράγματα έχουν λίγες πιθανότητες να πάνε στραβά: Εισαγωγή/διαγραφή: αναζήτηση του στοιχείου χωρίς κλείδωμα Κλείδωμα των κατάλληλων κόμβων Έλεγχος αν η δομή παραμένει συνεπής Αν όχι απελευθέρωση των κλειδωμάτων και νέα προσπάθεια Αναζήτηση: (μέθοδος contains) χρησιμοποιεί κλείδωμα 105
106 Optimistic synchronization: validate Ελέγχει αν η δομή είναι συνεπής, δηλαδή: Αν τα δύο στοιχεία (pred, curr) βρίσκονται ακόμα στη δομή και αν εξακολουθούν να είναι διαδοχικά Αν ο προηγούμενος κόμβος (pred) είναι προσβάσιμος από την αρχή της δομής, και Αν ο επόμενος του προηγούμενου είναι ο τρέχοντας (pred.next == curr) 106
107 Optimistic synchronization: validate private boolean validate(node pred, Node curr) { Node node = head; while (node.key <= pred.key) { if (node == pred) return pred.next == curr; node = node.next; return false; 107
108 Optimistic synchronization: validate private boolean validate(node pred, Node curr) { Node node = head; while (node.key <= pred.key) { if (node == pred) return pred.next == curr; node = node.next; return false; Πρόσβαση στον προηγούμενο κόμβο από την αρχή της δομής 108
109 Optimistic synchronization: validate private boolean validate(node pred, Node curr) { Node node = head; while (node.key <= pred.key) { if (node == pred) return pred.next == curr; node = node.next; return false; Έλεγχος αν το προηγούμενο δείχνει στο τρέχον 109
110 public boolean remove(item item) { int key = item.hashcode(); while (true) { Node pred = this.head; Node curr = pred.next; while (curr.key <= key) { if (item == curr.item) break; pred = curr; curr = curr.next; pred.lock(); curr.lock(); try { if (validate(pred,curr) { if (curr.item == item) { pred.next = curr.next; return true; else { return false; finally { pred.unlock(); curr.unlock(); Optimistic synchronization: remove 110
111 public boolean remove(item item) { int key = item.hashcode(); while (true) { Node pred = this.head; Node curr = pred.next; while (curr.key <= key) { if (item == curr.item) break; pred = curr; curr = curr.next; pred.lock(); curr.lock(); try { if (validate(pred,curr) { if (curr.item == item) { pred.next = curr.next; return true; else { return false; finally { pred.unlock(); curr.unlock(); Optimistic synchronization: remove Επαναληπτική προσπάθεια μέχρι να επιτύχει 111
112 public boolean remove(item item) { int key = item.hashcode(); while (true) { Node pred = this.head; Node curr = pred.next; while (curr.key <= key) { if (item == curr.item) break; pred = curr; curr = curr.next; pred.lock(); curr.lock(); try { if (validate(pred,curr) { if (curr.item == item) { pred.next = curr.next; return true; else { return false; finally { pred.unlock(); curr.unlock(); Optimistic synchronization: remove Διάσχιση της λίστας χωρίς κλειδώματα 112
113 public boolean remove(item item) { int key = item.hashcode(); while (true) { Node pred = this.head; Node curr = pred.next; while (curr.key <= key) { if (item == curr.item) break; pred = curr; curr = curr.next; pred.lock(); curr.lock(); try { if (validate(pred,curr) { if (curr.item == item) { pred.next = curr.next; return true; else { return false; finally { pred.unlock(); curr.unlock(); Optimistic synchronization: remove Κλειδώνει τον προηγούμενο και τον τρέχοντα 113
114 public boolean remove(item item) { int key = item.hashcode(); while (true) { Node pred = this.head; Node curr = pred.next; while (curr.key <= key) { if (item == curr.item) break; pred = curr; curr = curr.next; pred.lock(); curr.lock(); try { if (validate(pred,curr) { if (curr.item == item) { pred.next = curr.next; return true; else { return false; finally { pred.unlock(); curr.unlock(); Optimistic synchronization: remove Αν η δομή είναι συνεπής 114
115 public boolean remove(item item) { int key = item.hashcode(); while (true) { Node pred = this.head; Node curr = pred.next; while (curr.key <= key) { if (item == curr.item) break; pred = curr; curr = curr.next; pred.lock(); curr.lock(); try { if (validate(pred,curr) { if (curr.item == item) { pred.next = curr.next; return true; else { return false; finally { pred.unlock(); curr.unlock(); Optimistic synchronization: remove Αν η δομή είναι συνεπής, και υπάρχει το στοιχείο το αφαιρεί και επιστρέφει 115
116 public boolean remove(item item) { int key = item.hashcode(); while (true) { Node pred = this.head; Node curr = pred.next; while (curr.key <= key) { if (item == curr.item) break; pred = curr; curr = curr.next; pred.lock(); curr.lock(); try { if (validate(pred,curr) { if (curr.item == item) { pred.next = curr.next; return true; else { return false; finally { pred.unlock(); curr.unlock(); Optimistic synchronization: remove Αν η δομή είναι συνεπής, και δεν υπάρχει το στοιχείο, επιστρέφει 116
117 public boolean remove(item item) { int key = item.hashcode(); while (true) { Node pred = this.head; Node curr = pred.next; while (curr.key <= key) { if (item == curr.item) break; pred = curr; curr = curr.next; pred.lock(); curr.lock(); try { if (validate(pred,curr) { if (curr.item == item) { pred.next = curr.next; return true; else { return false; finally { pred.unlock(); curr.unlock(); Optimistic synchronization: remove Αν η δομή ΔΕΝ είναι συνεπής, ξεκλειδώνει 117
118 public boolean remove(item item) { int key = item.hashcode(); while (true) { Node pred = this.head; Node curr = pred.next; while (curr.key <= key) { if (item == curr.item) break; pred = curr; curr = curr.next; pred.lock(); curr.lock(); try { if (validate(pred,curr) { if (curr.item == item) { pred.next = curr.next; return true; else { return false; finally { pred.unlock(); curr.unlock(); Optimistic synchronization: remove Αν η δομή ΔΕΝ είναι συνεπής, ξεκλειδώνει, και ξαναπροσπαθεί 118
119 public boolean remove(item item) { int key = item.hashcode(); while (true) { Node pred = this.head; Node curr = pred.next; while (curr.key <= key) { if (item == curr.item) break; pred = curr; curr = curr.next; pred.lock(); curr.lock(); try { if (validate(pred,curr) { if (curr.item == item) { pred.next = curr.next; return true; else { return false; finally { pred.unlock(); curr.unlock(); Optimistic synchronization: remove Ανάλογα λειτουργεί η add Η contains χρησιμοποιεί κλειδώματα (γιατί;) 119
120 Lazy synchronization O optimistic συγχρονισμός λειτουργεί καλύτερα από το fine-grain συγχρονισμό αν: το κόστος να διατρέξουμε τη δομή 2 φορές χωρίς κλειδώματα είναι χαμηλότερο από το να την διατρέξουμε μία φορά με κλειδώματα Μειονέκτημα: η μέθοδος contains χρησιμοποιεί κλειδώματα Θέλουμε να το αποφύγουμε δεδομένου ότι αναμένουμε η contains να καλείται με πολύ μεγάλη συχνότητα Επόμενο βήμα βελτιστοποίησης: Η validate να μη διατρέχει τη λίστα από την αρχή Η contains να μη χρησιμοποιεί καθόλου κλειδώματα (wait-free) 120
121 Lazy synchronization Lazy synchronization: Προσθέτουμε στη δομή μία boolean μεταβλητή που δείχνει αν ο κόμβος βρίσκεται στη λίστα ή έχει διαγραφεί Η contains διατρέχει τη λίστα χωρίς να κλειδώνει. Ελέγχει και την επιπλέον Boolean μεταβλητή Η add διατρέχει τη λίστα, κλειδώνει και ελέγχει τη συνέπεια της δομής καλώντας τη validate H validate δεν διατρέχει τη λίστα από την αρχή αλλά κάνει τοπικούς ελέγχους στους κόμβους pred και curr Η remove είναι lazy, δηλαδή λειτουργεί σε 2 βήματα: Το 1 ο βήμα αφαιρεί λογικά τον κόμβο (θέτοντας τη boolean μεταβλητή σε false) To 2 ο βήμα αφαιρεί φυσικά τον κόμβο επαναθέτοντας του δείκτες 121
122 Lazy synchronization
123 Lazy synchronization Boolean μεταβλητή που δείχνει αν ο κόμβος είναι στη δομή 123
124 Lazy synchronization: remove remove(4)
125 Lazy synchronization: remove remove(4)
126 Lazy synchronization: remove remove(4) λογική αφαίρεση 126
127 Lazy synchronization: remove remove(4) φυσική αφαίρεση 127
128 Lazy synchronization: validate private boolean validate(node pred, Node curr) { return!pred.marked &&!curr.marked && pred.next == curr; 128
129 Lazy synchronization: validate private boolean validate(node pred, Node curr) { return!pred.marked &&!curr.marked && pred.next == curr; Δεν έχει σβηστεί ο προηγούμενος 129
130 Lazy synchronization: validate private boolean validate(node pred, Node curr) { return!pred.marked &&!curr.marked && pred.next == curr; Δεν έχει σβηστεί ο τρέχων 130
131 Lazy synchronization: validate private boolean validate(node pred, Node curr) { return!pred.marked &&!curr.marked && pred.next == curr; Ο προηγούμενος δείχνει τον τρέχοντα 131
132 Lazy synchronization: contains public boolean contains(t item) { int key = item.hashcode(); Node curr = this.head; while (curr.key < key) { curr = curr.next; return curr.key == key &&!curr.marked; Δεν χρησιμοποιεί κανένα κλείδωμα 132
133 Lazy synchronization: contains public boolean contains(t item) { int key = item.hashcode(); Node curr = this.head; while (curr.key < key) { curr = curr.next; return curr.key == key &&!curr.marked; Ελέγχει αν ο κόμβος έχει σβηστεί λογικά 133
134 public boolean remove(item item) { int key = item.hashcode(); while (true) { Node pred = this.head; Node curr = pred.next; while (curr.key <= key) { if (item == curr.item) break; pred = curr; curr = curr.next; pred.lock(); curr.lock(); try { if (validate(pred,curr) { if (curr.key == key) { curr.marked = true; pred.next = curr.next; return true; else { return false; finally { pred.unlock(); curr.unlock(); Lazy synchronization: remove 134
135 public boolean remove(item item) { int key = item.hashcode(); while (true) { Node pred = this.head; Node curr = pred.next; while (curr.key <= key) { if (item == curr.item) break; pred = curr; curr = curr.next; pred.lock(); curr.lock(); try { if (validate(pred,curr) { if (curr.key == key) { curr.marked = true; pred.next = curr.next; return true; else { return false; finally { pred.unlock(); curr.unlock(); Lazy synchronization: remove Αναζήτηση χωρίς κλείδωμα 135
136 public boolean remove(item item) { int key = item.hashcode(); while (true) { Node pred = this.head; Node curr = pred.next; while (curr.key <= key) { if (item == curr.item) break; pred = curr; curr = curr.next; pred.lock(); curr.lock(); try { if (validate(pred,curr) { if (curr.key == key) { curr.marked = true; pred.next = curr.next; return true; else { return false; finally { pred.unlock(); curr.unlock(); Lazy synchronization: remove Τοπικό κλείδωμα 136
137 public boolean remove(item item) { int key = item.hashcode(); while (true) { Node pred = this.head; Node curr = pred.next; while (curr.key <= key) { if (item == curr.item) break; pred = curr; curr = curr.next; pred.lock(); curr.lock(); try { if (validate(pred,curr) { if (curr.key == key) { curr.marked = true; pred.next = curr.next; return true; else { return false; finally { pred.unlock(); curr.unlock(); Lazy synchronization: remove Διαγραφή σε 2 βήματα: 137
138 public boolean remove(item item) { int key = item.hashcode(); while (true) { Node pred = this.head; Node curr = pred.next; while (curr.key <= key) { if (item == curr.item) break; pred = curr; curr = curr.next; pred.lock(); curr.lock(); try { if (validate(pred,curr) { if (curr.key == key) { curr.marked = true; pred.next = curr.next; return true; else { return false; finally { pred.unlock(); curr.unlock(); Lazy synchronization: remove Διαγραφή σε 2 βήματα: 1 ο Βήμα: Λογική διαγραφή 138
139 public boolean remove(item item) { int key = item.hashcode(); while (true) { Node pred = this.head; Node curr = pred.next; while (curr.key <= key) { if (item == curr.item) break; pred = curr; curr = curr.next; pred.lock(); curr.lock(); try { if (validate(pred,curr) { if (curr.key == key) { curr.marked = true; pred.next = curr.next; return true; else { return false; finally { pred.unlock(); curr.unlock(); Lazy synchronization: remove Διαγραφή σε 2 βήματα: 1 ο Βήμα: Λογική διαγραφή 2 ο Βήμα: Φυσική διαγραφή 139
140 public boolean remove(item item) { int key = item.hashcode(); while (true) { Node pred = this.head; Node curr = pred.next; while (curr.key <= key) { if (item == curr.item) break; pred = curr; curr = curr.next; pred.lock(); curr.lock(); try { if (validate(pred,curr) { if (curr.key == key) { curr.marked = true; pred.next = curr.next; return true; else { return false; finally { pred.unlock(); curr.unlock(); Lazy synchronization: remove Ομοίως η Add 140
141 Non-blocking synchronization Τελευταίο βήμα: Να απαλείψουμε πλήρως τα κλειδώματα και από τις 3 μεθόδους της δομής, add(), remove και contains(). Γιατί μας ενδιαφέρει να απαλείψουμε πλήρως τα κλειδώματα; Επίδοση: Υπό συνθήκες μπορεί να είναι ταχύτερο Ανθεκτικότητα (robustness): Αποφεύγουμε καταστάσεις κατά τις οποίες η αποτυχία ενός νήματος που κρατάει ένα κλείδωμα θα οδηγήσει σε αποτυχία όλης της εφαρμογής Ιδέα: Να χειριστούμε τα πεδία marked και next της δομής σαν μία ατομική μονάδα Οποιαδήποτε προσπάθεια ενημέρωσης του πεδίου next όταν το marked είναι true θα αποτύχει 141
142 Non-blocking synchronization: Ζητήματα υλοποίησης address marked field Η δομή ως τώρα 142
143 Non-blocking synchronization: Ζητήματα υλοποίησης Συμπυκνώνονται τα δύο κρίσιμα πεδία της δομής σε μία packed μορφή την οποία ο επεξεργαστής μπορεί να χειριστεί ατομικά address marked bit Π.χ. AtomicMarkableReference class Java.util.concurrent.atomic package 143
144 public T get(boolean[] marked); public boolean compareandset( T expectedref, T updateref, boolean expectedmark, boolean updatemark); public boolean attemptmark( T expectedref, boolean updatemark); AtomicMarkableReference 144
145 public T get(boolean[] marked); AtomicMarkableReference public Επιστρέφει boolean τη διεύθυνση compareandset( του αντικειμένου T και αποθηκεύει το mark T expectedref, στη θέση 0 του πίνακα που περνιέται σαν παράμετρος T updateref, boolean expectedmark, boolean updatemark); public boolean attemptmark( T expectedref, boolean updatemark); 145
146 public T get(boolean[] marked); public boolean compareandset( T expectedref, T updateref, boolean expectedmark, boolean updatemark); AtomicMarkableReference Ελέγχει publicκαι boolean αν επιτύχει attemptmark( ενημερώνει ΚΑΙ τα δύο πεδία T expectedref, boolean updatemark); 146
147 public T get(boolean[] marked); public boolean compareandset( T expectedref, T updateref, boolean expectedmark, boolean updatemark); public boolean attemptmark( T expectedref, boolean updatemark); AtomicMarkableReference Ενημέρωνει το mark αν η διεύθυνση είναι η αναμενόμενη 147
148 Non-blocking synchronization Τελευταίο βήμα: Να απαλείψουμε πλήρως τα κλειδώματα και από τις 3 μεθόδους της δομής, add(), remove και contains(). Ιδέα: Να χειριστούμε τα πεδία marked και next της δομής σαν μία ατομική μονάδα Οποιαδήποτε προσπάθεια ενημέρωσης του πεδίου next όταν το marked είναι true (ο κόμβος δεν υπάρχει) θα αποτύχει Η αφαίρεση ενός κλειδιού περιλαμβάνει την ενημέρωση του πεδίου marked (και μία μόνο απόπειρα να ενημερωθούν οι διευθύνσεις) Κάθε νήμα που διατρέχει τη λίστα εκτελώντας την add() και remove() αφαιρεί φυσικά τους κόμβους που συναντά να έχουν σβηστεί Η αποτυχία για ατομική ενημέρωση οδηγεί στην επαναπροσπάθεια με διάτρεξη από την αρχή της λίστας 148
149 Non-blocking synchronization: βοηθητική κλάση Window και μέθοδος find() Χρησιμοποιείται από την add() και τη remove() για να βρεθεί το σημείο που θα γίνει η εισαγωγή ή το στοιχείο που θα αφαιρεθεί Επιστρέφει ένα δείκτη στο ακριβώς μικρότερο στοιχείο (από αυτό που θα προστεθεί ή αφαιρεθεί) και ένα δείκτη στο αμέσως μεγαλύτερο ή ίσο στοιχείο Αν συναντήσει στοιχεία που έχουν σβηστεί λογικά τα σβήνει και φυσικά 149
150 public Window find(node head, int key) { Node pred = null, curr = null succ = null; boolean[] marked = {false; retry: while (true) { 150 pred = head; curr = pred.next.getreference(); while (true) succ = curr.next.get(marked); while (marked[0]) { snip = pred.next.compareandset(curr, succ, false, false); if (!snip) continue retry; curr = succ; succ = curr.next.get(marked); if (curr.key >= key) return new Window(pred,curr); pred = curr; curr = succ; Non-blocking synchronization: find()
151 public Window find(node head, int key) { Node pred = null, curr = null succ = null; boolean[] marked = {false; retry: while (true) { 151 pred = head; curr = pred.next.getreference(); while (true) { succ = curr.next.get(marked); while (marked[0]) { snip = pred.next.compareandset(curr, succ, false, false); if (!snip) continue retry; curr = succ; succ = curr.next.get(marked); if (curr.key >= key) return new Window(pred, curr); pred = curr; curr = succ; Non-blocking synchronization: find() Διατρέχει τη λίστα μέχρι να βρει ένα στοιχείο μεγαλύτερο από το ζητούμενο
152 public Window find(node head, int key) { Node pred = null, curr = null succ = null; boolean[] marked = {false; retry: while (true) { 152 pred = head; curr = pred.next.getreference(); while (true) succ = curr.next.get(marked); while (marked[0]) { snip = pred.next.compareandset(curr, succ, false, false); if (!snip) continue retry; curr = succ; succ = curr.next.get(marked); if (curr.key >= key) return new Window(pred,curr); pred = curr; curr = succ; Non-blocking synchronization: find() Αν βρεθεί στοιχείο που έχει σβηστεί λογικά, σβήνεται και φυσικά
153 public Window find(node head, int key) { Node pred = null, curr = null succ = null; boolean[] marked = {false; retry: while (true) { 153 pred = head; curr = pred.next.getreference(); while (true) succ = curr.next.get(marked); while (marked[0]) { snip = pred.next.compareandset(curr, succ, false, false); if (!snip) continue retry; curr = succ; succ = curr.next.get(marked); if (curr.key >= key) return new Window(pred,curr); pred = curr; curr = succ; Non-blocking synchronization: find() Αν αποτύχει η ατομική ενημέρωση η διαδικασία ξεκινά από την αρχή
154 public boolean remove(t item) { boolean snip; while (true) { Window window = find(head, key); Node pred = window.pred, curr = window.curr; if (curr.key!= key) { return false; else { Node succ = curr.next.getreference(); snip = curr.next.attemptmark(succ, true); if (!snip) continue; pred.next.compareandset(curr, succ, false, false); return true; Non-blocking synchronization: remove() 154
155 public boolean remove(t item) { boolean snip; while (true) { Window window = find(head, key); Node pred = window.pred, curr = window.curr; if (curr.key!= key) { return false; else { Node succ = curr.next.getreference(); snip = curr.next.attemptmark(succ, true); if (!snip) continue; pred.next.compareandset(curr, succ, false, false); return true; Non-blocking synchronization: remove() Αφαιρεί λογικά τον κόμβο 155
156 public boolean remove(t item) { boolean snip; while (true) { Window window = find(head, key); Node pred = window.pred, curr = window.curr; if (curr.key!= key) { return false; else { Node succ = curr.next.getreference(); snip = curr.next.attemptmark(succ, true); if (!snip) continue; pred.next.compareandset(curr, succ, false, false); return true; Non-blocking synchronization: remove() Αφαιρεί λογικά τον κόμβο. Αν αποτύχει (γιατί ο κόμβος έχει εντωμεταξύ αφαιρεθεί και φυσικά) ξαναξεκινά 156
157 public boolean remove(t item) { boolean snip; while (true) { Window window = find(head, key); Node pred = window.pred, curr = window.curr; if (curr.key!= key) { return false; else { Node succ = curr.next.getreference(); snip = curr.next.attemptmark(succ, true); if (!snip) continue; pred.next.compareandset(curr, succ, false, false); return true; Non-blocking synchronization: remove() Κάνει μία απόπειρα να αφαιρέσει και φυσικά τον κόμβο 157
158 public boolean add(t item) { boolean splice; while (true) { Window window = find(head, key); Node pred = window.pred, curr = window.curr; if (curr.key == key) { return false; else { Node node = new Node(item); node.next = new AtomicMarkableRef(curr, false); if (pred.next.compareandset(curr, node, false, false)) return true; Non-blocking synchronization: add() 158
159 public boolean add(t item) { boolean splice; while (true) { Window window = find(head, key); Node pred = window.pred, curr = window.curr; if (curr.key == key) { return false; else { Node node = new Node(item); node.next = new AtomicMarkableRef(curr, false); if (pred.next.compareandset(curr, node, false, false)) return true; Non-blocking synchronization: add() Δημιουργία και αρχικοποίηση νέου κόμβου 159
160 public boolean add(t item) { boolean splice; while (true) { Window window = find(head, key); Node pred = window.pred, curr = window.curr; if (curr.key == key) { return false; else { Node node = new Node(item); node.next = new AtomicMarkableRef(curr, false); if (pred.next.compareandset(curr, node, false, false)) return true; Non-blocking synchronization: add() Διασύνδεση νέου κόμβου στη δομή 160
161 public boolean add(t item) { boolean splice; while (true) { Window window = find(head, key); Node pred = window.pred, curr = window.curr; if (curr.key == key) { return false; else { Node node = new Node(item); node.next = new AtomicMarkableRef(curr, false); if (pred.next.compareandset(curr, node, false, false)) return true; Non-blocking synchronization: add() Αν αποτύχει, ξαναπροσπαθεί 161
162 public boolean contains(tt item) { boolean marked; int key = item.hashcode(); Node curr = this.head; while (curr.key < key) curr = curr.next; Node succ = curr.next.get(marked); return (curr.key == key &&!marked[0]) Non-blocking synchronization: contains() Wait-free μέθοδος 162
163 Ιδιότητες προόδου στα σχήματα Blocking και Non-blocking Κάποιος προοδεύει Όλοι προοδεύουν Blocking Χωρίς αδιέξοδο (deadlock-free) Χωρίς λιμοκτονία (starvation-free) Non-blocking Lock-free Wait-free 163
164 Σύνοψη contains add remove validate Coarse-grain 1 lock 1 lock 1 lock no Fine-grain hand-over-hand locking hand-over-hand locking hand-over-hand locking Optimistic local locking local locking local locking διάσχιση από την αρχή Lazy no locking local locking local locking local checks Non-blocking wait-free lock-free (with retries) lock-free (with retries) no no 164
165 Further reading Chapters 7, 8, 9 from: The Art of Multiprocessor Programming By Maurice Herlihy, Nir Shavit The following joke circulated in Italy in the 1920s. According to Mussolini, the ideal citizen is intelligent, honest, and Fascist. Unfortunately, no one is perfect, which explains why everyone you meet is either intelligent and Fascist but not honest, honest and Fascist but not intelligent, or honest and intelligent but not Fascist. 165
Συγχρονισμός. Εθνικό Μετσόβιο Πολυτεχνείο Σχολή Ηλεκτρολόγων Μηχ. και Μηχανικών Υπολογιστών Εργαστήριο Υπολογιστικών Συστημάτων
Εθνικό Μετσόβιο Πολυτεχνείο Σχολή Ηλεκτρολόγων Μηχ. και Μηχανικών Υπολογιστών Εργαστήριο Υπολογιστικών Συστημάτων Συγχρονισμός 9 ο Εξάμηνο Σύνοψη Το πρόβλημα του συγχρονισμού Βασικοί μηχανισμοί Κλειδώματα
Συγχρονισμός. Εθνικό Μετσόβιο Πολυτεχνείο Σχολή Ηλεκτρολόγων Μηχ. και Μηχανικών Υπολογιστών Εργαστήριο Υπολογιστικών Συστημάτων
Εθνικό Μετσόβιο Πολυτεχνείο Σχολή Ηλεκτρολόγων Μηχ. και Μηχανικών Υπολογιστών Εργαστήριο Υπολογιστικών Συστημάτων Συγχρονισμός 9 ο Εξάμηνο Σύνοψη Το πρόβλημα του συγχρονισμού Βασικοί μηχανισμοί Κλειδώματα
Συγχρονισμός Μέρος Α : Κρίσιμο τμήμα και κλειδώματα
Εθνικό Μετσόβιο Πολυτεχνείο Σχολή Ηλεκτρολόγων Μηχ. και Μηχανικών Υπολογιστών Εργαστήριο Υπολογιστικών Συστημάτων Συγχρονισμός Μέρος Α : Κρίσιμο τμήμα και κλειδώματα 9 ο Εξάμηνο Η ανάγκη για συγχρονισμό
Dr. Garmpis Aristogiannis - EPDO TEI Messolonghi
Προϋποθέσεις για Αµοιβαίο Αποκλεισµό Μόνο µία διεργασία σε κρίσιµο τµήµασεκοινό πόρο Μία διεργασία που σταµατά σε µη κρίσιµο σηµείο δεν πρέπει να επιρεάζει τις υπόλοιπες διεργασίες εν πρέπει να υπάρχει
Λειτουργικά Συστήματα Η/Υ
Λειτουργικά Συστήματα Η/Υ Κεφάλαιο 5 «Αμοιβαίος Αποκλεισμός» Διδάσκων: Δ Λιαροκάπης Διαφάνειες: Π. Χατζηδούκας 1 Αμοιβαίος Αποκλεισμός 1. Εισαγωγή 2. Κρίσιμα τμήματα (Critical Sections) 3. Υλοποίηση του
Διεργασίες (Processes)
Διεργασία (process) ή καθήκον (task) Διεργασίες (Processes) στοιχειώδης οντότητα/δραστηριότητα υπολογισμού (processing entity/activity) εκτέλεση ενός προγράμματος ένα (κύριο) νήμα (thread)/ρεύμα ελέγχου/εκτέλεσης
Παρουσίαση 5 ης Άσκησης:
Εθνικό Μετσόβιο Πολυτεχνείο Σχολή Ηλεκτρολόγων Μηχ. και Μηχανικών Υπολογιστών Εργαστήριο Υπολογιστικών Συστημάτων Παρουσίαση 5 ης Άσκησης: Θέματα Συγχρονισμού σε Σύγχρονα Πολυπύρηνα Συστήματα Ακ. Έτος
Αμοιβαίος αποκλεισμός με κοινή μνήμη. Ταυτόχρονος Προγραμματισμός 1
Αμοιβαίος αποκλεισμός με κοινή μνήμη 1 lalis@inf.uth.gr Το πρόβλημα Έστω ότι δύο η περισσότερα νήματα επιθυμούν να προσπελάσουν έναν κοινό πόρο, που όμως δεν μπορεί να χρησιμοποιηθεί ταυτόχρονα Η χρήση
Παρουσίαση 5 ης Άσκησης:
Εθνικό Μετσόβιο Πολυτεχνείο Σχολή Ηλεκτρολόγων Μηχ. και Μηχανικών Υπολογιστών Εργαστήριο Υπολογιστικών Συστημάτων Παρουσίαση 5 ης Άσκησης: Θέματα Συγχρονισμού σε Σύγχρονα Πολυπύρηνα Συστήματα Ακ. Έτος
HY-486 Αρχές Κατανεμημένου Υπολογισμού Εαρινό Εξάμηνο
HY-486 Αρχές Κατανεμημένου Υπολογισμού Εαρινό Εξάμηνο 2017-2018 Πρώτη Προγραμματιστική Εργασία Προθεσμία παράδοσης: Δευτέρα 30/4 στις 23:59. 1. Γενική Περιγραφή Στην πρώτη προγραμματιστική εργασία καλείστε
HY-486 Αρχές Κατανεμημένου Υπολογισμού
HY-486 Αρχές Κατανεμημένου Υπολογισμού Εαρινό Εξάμηνο 2016-2017 Πρώτη Προγραμματιστική Εργασία Προθεσμία παράδοσης: Τρίτη 2/5 στις 23:59. 1. Γενική Περιγραφή Στην πρώτη προγραμματιστική εργασία καλείστε
Λειτουργικά Συστήματα
1 Ελληνική Δημοκρατία Τεχνολογικό Εκπαιδευτικό Ίδρυμα Ηπείρου Λειτουργικά Συστήματα Ενότητα 5 : Αμοιβαίος Αποκλεισμός Δημήτριος Λιαροκάπης 2 Ανοιχτά Ακαδημαϊκά Μαθήματα στο ΤΕΙ Ηπείρου Τμήμα Μηχανικών
Παράλληλη Επεξεργασία
Παράλληλη Επεξεργασία Φροντιστήριο: Συγχρονισμός (συνέχεια) Μεταβλητές υπό συνθήκη Εργαστήριο Πληροφοριακών Συστημάτων Υψηλής Επίδοσης Parallel and Distributed Systems Group Συγχρονισμός μεταξύ νημάτων
Συλλογές, Στοίβες και Ουρές
Συλλογές, Στοίβες και Ουρές Σε πολλές εφαρμογές μας αρκεί η αναπαράσταση ενός δυναμικού συνόλου με μια δομή δεδομένων η οποία δεν υποστηρίζει την αναζήτηση οποιουδήποτε στοιχείου. Συλλογή (bag) : Επιστρέφει
Προσπέλαση σύνθετων δομών δεδομένων χωρίς καθολικό κλείδωμα
Προσπέλαση σύνθετων δομών δεδομένων χωρίς καθολικό κλείδωμα ΙΙΙ 1 lalis@inf.uth.gr Προβλήματα με κλείδωμα Υπερβολική σειριοποίηση / άσκοπη αναμονή Κόστος συγχρονισμού Αδιέξοδα Απότομος τερματισμός νημάτων
Ελεγκτές/Παρακολουθητές (Monitors) Ταυτόχρονος Προγραμματισμός 1
Ελεγκτές/Παρακολουθητές (Monitors) 1 lalis@inf.uth.gr Ελεγκτές Αμοιβαίος αποκλεισμός στο πλαίσιο ενός τμήματος λογισμικού που προσπελάζεται με δομημένο τρόπο, μέσω προκαθορισμένης διασύνδεσης (API) Ο συγχρονισμός
Προσπέλαση σύνθετων δομών δεδομένων χωρίς καθολικό κλείδωμα
Προσπέλαση σύνθετων δομών δεδομένων χωρίς καθολικό κλείδωμα ΙΙΙ 1 lalis@inf.uth.gr Προβλήματα με κλείδωμα Υπερβολική σειριοποίηση / άσκοπη αναμονή Κόστος συγχρονισμού Αδιέξοδα Απότομος τερματισμός νημάτων
Αμοιβαίος αποκλεισμός με κοινή μνήμη. Ταυτόχρονος Προγραμματισμός 1
Αμοιβαίος αποκλεισμός με κοινή μνήμη 1 lalis@inf.uth.gr Το πρόβλημα Έστω ότι δύο η περισσότερα νήματα επιθυμούν να προσπελάσουν έναν κοινό πόρο, που όμως δεν μπορεί να χρησιμοποιηθεί ταυτόχρονα Η χρήση
Υ- 07 Παράλληλα Συστήματα Transac9onal memory
Υ- 07 Παράλληλα Συστήματα Transac9onal memory Αρης Ευθυμίου Παρ. προγρ/μός με κλειδιά Χαμηλού επιπέδου πολύ κοντά στα μέσα και τις δομές του υλικού πολλές λεπτομέρειες, εύκολα γίνεται λάθος χαμηλή παραγωγικότητα
Λειτουργικά Συστήματα
ΑΡΙΣΤΟΤΕΛΕΙΟ ΠΑΝΕΠΙΣΤΗΜΙΟ ΘΕΣΣΑΛΟΝΙΚΗΣ ΑΝΟΙΧΤΑ ΑΚΑΔΗΜΑΙΚΑ ΜΑΘΗΜΑΤΑ Λειτουργικά Συστήματα Ενότητα 4α: Σημαφόροι, Πρόβλημα Συνδαιτυμόνων Φιλοσόφων, Αδιέξοδα Αθηνά Βακάλη Άδειες Χρήσης Το παρόν εκπαιδευτικό
Μηχανισμοί και προγραμματιστικές δομές συγχρονισμού. Προβλήματα συγχρονισμού (και λύσεις)
Άδεια Χρήσης Το παρόν εκπαιδευτικό υλικό υπόκειται σε άδειες χρήσης Creative Commons. Για εκπαιδευτικό υλικό, όπως εικόνες, που υπόκειται σε άδεια χρήσης άλλου τύπου, αυτή πρέπει να αναφέρεται ρητώς. Περιεχόμενα
ΚΕΦΑΛΑΙΟ 9. Ταυτόχρονος προγραμματισμός και νήματα. 9.1 Εισαγωγή
ΚΕΦΑΛΑΙΟ 9 Ταυτόχρονος προγραμματισμός και νήματα Σύνοψη Σε αυτό το κεφάλαιο πραγματευόμαστε τον ταυτόχρονο προγραμματισμό με τη χρήση νημάτων. Η έμφαση είναι στην κατανόηση βασικών λειτουργιών των νημάτων
Ελεγκτές/Παρακολουθητές (Monitors) Ταυτόχρονος Προγραμματισμός 1
Ελεγκτές/Παρακολουθητές (Monitors) 1 lalis@inf.uth.gr Ελεγκτές Αμοιβαίος αποκλεισμός στο πλαίσιο ενός τμήματος λογισμικού που προσπελάζεται με δομημένο τρόπο, μέσω προκαθορισμένης διασύνδεσης (API) Ο συγχρονισμός
Σηματοφόροι (Σηματοφορείς) Ταυτόχρονος Προγραμματισμός 1
Σηματοφόροι (Σηματοφορείς) 1 lalis@inf.uth.gr Αποφυγή ενεργής αναμονής if () { WAIT(); Μπορεί να γίνει εναλλαγή αφού το νήμα κάνει τον έλεγχο της συνθήκης αναμονής και την βρει αληθή, αλλά προτού αυτό
Διάλεξη 07: Λίστες Ι Υλοποίηση & Εφαρμογές
Διάλεξη 07: Λίστες Ι Υλοποίηση & Εφαρμογές Στην ενότητα αυτή θα μελετηθούν τα εξής επιμέρους θέματα: Ευθύγραμμες Απλά Συνδεδεμένες Λίστες (εισαγωγή, εύρεση, διαγραφή) Ευθύγραμμες Διπλά Συνδεδεμένες Λίστες
Αμοιβαίος αποκλεισμός με κοινή μνήμη. Ταυτόχρονος Προγραμματισμός 1
Αμοιβαίος αποκλεισμός με κοινή μνήμη 1 lalis@inf.uth.gr Το πρόβλημα Έστω ότι δύο η περισσότερα νήματα επιθυμούν να προσπελάσουν έναν κοινό πόρο, που όμως δεν μπορεί να χρησιμοποιηθεί ταυτόχρονα Η χρήση
Λειτουργικά Συστήματα (ΗΥ222)
Λειτουργικά Συστήματα (ΗΥ222) Ταυτοχρονισμός, Συγχρονισμός Πολλαπλές Διεργασίες/Νήματα σε 1 Κοινωνία: Προβλήματα; «Κοινωνικές Γιάννης διεργασίες/νήματα»: Διαβάζουν/γράφουν στον ίδιο χώρο. Αποτέλεσμα; Πιθανότατα
Εθνικό Μετσόβιο Πολυτεχνείο Σχολή Ηλεκτρολόγων Μηχ. και Μηχανικών Υπολογιστών Εργαστήριο Υπολογιστικών Συστημάτων. Συγχρονισμός
Εθνικό Μετσόβιο Πολυτεχνείο Σχολή Ηλεκτρολόγων Μηχ. και Μηχανικών Υπολογιστών Εργαστήριο Υπολογιστικών Συστημάτων 3 η Εργαστηριακή Άσκηση: Συγχρονισμός Λειτουργικά Συστήματα Υπολογιστών 7ο Εξάμηνο, 2016-2017
Νήµαταστην Java. Συγχρονισµός νηµάτων Επικοινωνία νηµάτων Εκτελέσιµα αντικείµενα Νήµατα δαίµονες Οµάδες νηµάτων. Κατανεµηµένα Συστήµατα 11-1
Νήµαταστην Java Συγχρονισµός νηµάτων Επικοινωνία νηµάτων Εκτελέσιµα αντικείµενα Νήµατα δαίµονες Οµάδες νηµάτων Κατανεµηµένα Συστήµατα 11-1 Νήµαταστην Java γεννηθείσα notify notifyall έτοιµη start εκπνοή
Διδάσκων: Παναγιώτης Ανδρέου
Διάλεξη 22: Συγχρονισμός (Concurrency) Στην ενότητα αυτή θα μελετηθούν τα εξής επιμέρους θέματα: - Διεργασίες (processes) και Νήματα (threads) - Συγχρονισμός Νημάτων, Προβλήματα, Λύσεις - Οι τροποποιητές
Εθνικό Μετσόβιο Πολυτεχνείο Σχολή Ηλεκτρολόγων Μηχ. και Μηχανικών Υπολογιστών Εργαστήριο Υπολογιστικών Συστημάτων. Συγχρονισμός
Εθνικό Μετσόβιο Πολυτεχνείο Σχολή Ηλεκτρολόγων Μηχ. και Μηχανικών Υπολογιστών Εργαστήριο Υπολογιστικών Συστημάτων 3 η Εργαστηριακή Άσκηση: Συγχρονισμός Λειτουργικά Συστήματα Υπολογιστών 7ο Εξάμηνο, 2017-2018
Δομές Δεδομένων. Ενότητα 4: Ο ΑΤΔ Λίστα & Υλοποίηση Λίστας με σειριακή αποθήκευση- Ο ΑΤΔ Συνδεδεμένη Λίστα- Υλοποίηση ΑΤΔ Συνδεδεμένη Λίστα με πίνακα
Ενότητα 4: Ο ΑΤΔ Λίστα & Υλοποίηση Λίστας με σειριακή αποθήκευση- Ο ΑΤΔ Συνδεδεμένη Λίστα- Υλοποίηση ΑΤΔ Συνδεδεμένη Λίστα με πίνακα Καθηγήτρια Μαρία Σατρατζέμη Άδειες Χρήσης Το παρόν εκπαιδευτικό υλικό
Υ- 07 Παράλληλα Συστήματα Συνέπεια και συνοχή μνήμης
Υ- 07 Παράλληλα Συστήματα Συνέπεια και συνοχή μνήμης Αρης Ευθυμίου Λειτουργία μνήμης Η μνήμη είναι ένας πίνακας αποθήκευσης Οταν διαβάζουμε μια θέση, περιμένουμε να πάρουμε την τελευταία τιμή που έχει
Εισαγωγή στα Λειτουργικά Συστήματα
Εισαγωγή στα Λειτουργικά Συστήματα Ενότητα 4: Διεργασίες ΙΙ Γεώργιος Φ. Φραγκούλης Τμήμα Ηλεκτρολόγων Μηχανικών Άδειες Χρήσης Το παρόν εκπαιδευτικό υλικό υπόκειται σε άδειες χρήσης Creative Commons. Για
Διδάσκων: Παναγιώτης Ανδρέου
Διάλεξη 12: Δέντρα ΙΙ -Δυαδικά Δέντρα Στην ενότητα αυτή θα μελετηθούν τα εξής επιμέρους θέματα: - Δυαδικά Δένδρα - Δυαδικά Δένδρα Αναζήτησης(ΔΔΑ) - Εύρεση Τυχαίου, Μέγιστου, Μικρότερου στοιχείου - Εισαγωγή
Σηματοφόροι (Σηματοφορείς) Ταυτόχρονος Προγραμματισμός 1
Σηματοφόροι (Σηματοφορείς) 1 lalis@inf.uth.gr Αποφυγή ενεργής αναμονής εναλλαγή if/while () { WAIT(); Μπορεί να γίνει εναλλαγή αφού το νήμα κάνει τον έλεγχο της συνθήκης αναμονής και την βρει αληθή, αλλά
Προβλήματα ταυτόχρονης εκτέλεσης (για νήματα με κοινή μνήμη)
Προβλήματα ταυτόχρονης εκτέλεσης (για νήματα με κοινή μνήμη) ΙΙΙ 1 lalis@inf.uth.gr Ταυτόχρονη εκτέλεση Ο προγραμματιστής δεν ελέγχει (άμεσα) την εκτέλεση/εναλλαγή των νημάτων Δεν γνωρίζει πότε θα αρχίσει
3 η ΑΣΚΗΣΗ. Προηγμένα Θέματα Αρχιτεκτονικής Υπολογιστών
ΕΘΝΙΚΟ ΜΕΤΣΟΒΙΟ ΠΟΛΥΤΕΧΝΕΙΟ ΣΧΟΛΗ ΗΛΕΚΤΡΟΛΟΓΩΝ ΜΗΧΑΝΙΚΩΝ ΚΑΙ ΜΗΧΑΝΙΚΩΝ ΥΠΟΛΟΓΙΣΤΩΝ ΤΟΜΕΑΣ ΤΕΧΝΟΛΟΓΙΑΣ ΠΛΗΡΟΦΟΡΙΚΗΣ ΚΑΙ ΥΠΟΛΟΓΙΣΤΩΝ ΕΡΓΑΣΤΗΡΙΟ ΥΠΟΛΟΓΙΣΤΙΚΩΝ ΣΥΣΤΗΜΑΤΩΝ www.cslab.ece.ntua.gr 3 η ΑΣΚΗΣΗ Προηγμένα
Τ.Ε.Ι. Μεσολογγίου, Τµήµα τηλεπικοινωνιακών Συστημάτων & Δικτύων
Εργαστήριο Java Lab09 Αντικείμενο: Πολυνηματικές εφαρμογές Η χρήση περισσότερων από μιας ροής εντολών μέσα σε ένα πρόγραμμα είναι γνωστή ως multithreading. H κάθε μια ροή εντολών μέσα στο πρόγραμμα ονομάζεται
Ιδιοκτησία Αντικειµένου
Software Transactional Memory H STM υποστηρίζει την εκτέλεση δοσοληψιών από τις διεργασίες, οι οποίες περιέχουν λειτουργίες που ο χρήστης θέλει να εκτελέσει στα διαµοιραζόµενα αντικείµενα. H STM εγγυάται
Δομές Δεδομένων. Ενότητα 7: Άλλες παραλλαγές Συνδεδεμένων Λιστών-Παράσταση Αραιού Πολυωνύμου με Συνδεδεμένη Λίστα. Καθηγήτρια Μαρία Σατρατζέμη
Ενότητα 7: Άλλες παραλλαγές Συνδεδεμένων Λιστών-Παράσταση Αραιού Πολυωνύμου με Συνδεδεμένη Λίστα Καθηγήτρια Μαρία Σατρατζέμη Άδειες Χρήσης Το παρόν εκπαιδευτικό υλικό υπόκειται σε άδειες χρήσης Creative
ΕΘΝΙΚΟ ΜΕΤΣΟΒΙΟ ΠΟΛΥΤΕΧΝΕΙΟ ΣΧΟΛΗ ΗΛΕΚΤΡΟΛΟΓΩΝ ΜΗΧΑΝΙΚΩΝ ΚΑΙ ΜΗΧΑΝΙΚΩΝ ΥΠΟΛΟΓΙΣΤΩΝ ΤΟΜΕΑΣ ΤΕΧΝΟΛΟΓΙΑΣ ΠΛΗΡΟΦΟΡΙΚΗΣ ΚΑΙ ΥΠΟΛΟΓΙΣΤΩΝ
ΕΘΝΙΚΟ ΜΕΤΣΟΒΙΟ ΠΟΛΥΤΕΧΝΕΙΟ ΣΧΟΛΗ ΗΛΕΚΤΡΟΛΟΓΩΝ ΜΗΧΑΝΙΚΩΝ ΚΑΙ ΜΗΧΑΝΙΚΩΝ ΥΠΟΛΟΓΙΣΤΩΝ ΤΟΜΕΑΣ ΤΕΧΝΟΛΟΓΙΑΣ ΠΛΗΡΟΦΟΡΙΚΗΣ ΚΑΙ ΥΠΟΛΟΓΙΣΤΩΝ Ε Ρ Γ Α Σ ΤΗΡΙΟ ΥΠΟΛ Ο Γ Ι Σ ΤΙ Κ Ω Ν Σ Υ Σ ΤΗ ΜΑ ΤΩΝ www. c s l a b.
Parallel Architectures
Parallel Architectures Memory Consistency + Synchronization Figures, examples από 1. Transactional Memory, D. Wood, Lecture Notes in ACACES 2009 2. Krste Asanović s s Lecture Notes, University of California,
ΣυγχρονισµόςσεΣυστήµατα ΠολλαπλώνΝηµάτων
ΣυγχρονισµόςσεΣυστήµατα ΠολλαπλώνΝηµάτων Συστήµατα Παράλληλης Επεξεργασίας Εργαστήριο Υπολογιστικών Συστηµάτων ΕΜΠ Κορνήλιος Κούρτης kkourt@cslab.ece.ntua.gr p. 1 Περιβάλλον Πολλαπλών Νηµάτων Threads T0
2.4 Κλασσικά Προβλήματα IPC
2.4 Κλασσικά Προβλήματα IPC 1 Οι φιλόσοφοι που γευματίζουν - Dining Philosophers Μια πρώτη λύση για Ν φιλοσόφους: philosopher (i) while (1) { think; take_fork(i);/* πάρε αριστερό ξυλάκι */ take_fork(i+1
Παράλληλη Επεξεργασία
Παράλληλη Επεξεργασία Φροντιστήριο: Νήματα & Συγχρονισμός Μεταβλητές κλειδιά Φράγματα Εργαστήριο Πληροφοριακών Συστημάτων Υψηλής Επίδοσης Parallel and Distributed Systems Group Συγχρονισμός μεταξύ νημάτων
Διάλεξη 16: Σωροί. Στην ενότητα αυτή θα μελετηθούν τα εξής επιμέρους θέματα: - Ουρές Προτεραιότητας - Ο ΑΤΔ Σωρός, Υλοποίηση και πράξεις
ΕΠΛ231 Δομές Δεδομένων και Αλγόριθμοι 1 Διάλεξη 16: Σωροί Στην ενότητα αυτή θα μελετηθούν τα εξής επιμέρους θέματα: - Ουρές Προτεραιότητας - Ο ΑΤΔ Σωρός, Υλοποίηση και πράξεις Ουρά Προτεραιότητας Η δομή
Διάλεξη 10: Αλγόριθμοι Αμοιβαίου Αποκλεισμού σε περιβάλλον ανταλλαγής μηνυμάτων. ΕΠΛ 432: Κατανεμημένοι Αλγόριθμοι
Διάλεξη 10: Αλγόριθμοι Αμοιβαίου Αποκλεισμού σε περιβάλλον ανταλλαγής μηνυμάτων ΕΠΛ 432: Κατανεμημένοι Αλγόριθμοι Τι θα δούμε σήμερα Αλγόριθμος Χρήση Συντονιστή Αλγόριθμος του Lamport Αλγόριθμος LeLann:
Διάλεξη 12: Δέντρα ΙΙ Δυαδικά Δέντρα
Διάλεξη 12: Δέντρα ΙΙ Δυαδικά Δέντρα Στην ενότητα αυτή θα μελετηθούν τα εξής επιμέρους θέματα: Δυαδικά Δένδρα Δυαδικά Δένδρα Αναζήτησης (ΔΔΑ) Εύρεση Τυχαίου, Μέγιστου, Μικρότερου στοιχείου Εισαγωγή στοιχείου
Εργαστήριο 14. Συγχρονισμός Νημάτων (χρήση pthread_mutex_t, pthread_cond_t)
Εργαστήριο 14 Συγχρονισμός Νημάτων (χρήση pthread_mutex_t, pthread_cond_t) Να γράψετε πρόγραμμα που να δημιουργεί 1 νήμα Έτσι στο πρόγραμμα σας θα υπάρχουν 2 νήματα (το ένα νήμα είναι το αρχικό νήμα που
Υλοποίηση Σηματοφόρων
Υλοποίηση Σηματοφόρων 1 lalis@inf.uth.gr Υλοποίηση σε επίπεδο συστήματος Εσωτερική κατάσταση: Ένας ακέραιος για την αποθήκευση της τιμής του σηματοφόρου Μια ουρά αναμονής που τοποθετείται ένα νήμα όταν
Επικοινωνία µεταξύ ιεργασιών και Σύνδροµες ιεργασίες
Επικοινωνία µεταξύ ιεργασιών και Σύνδροµες ιεργασίες Interprocess Communication and Concurrent Processes Περίληψη Σύνδροµος Προγραµµατισµός Συνθήκη συναγωνισµού Συγχρονισµός διεργασιών Κρίσιµες περιοχές
Στοιχειώδεις Δομές Δεδομένων
Στοιχειώδεις Δομές Δεδομένων Τύποι δεδομένων στη Java Ακέραιοι (int, long) Αριθμοί κινητής υποδιαστολής (float, double) Χαρακτήρες (char) Δυαδικοί (boolean) Από τους παραπάνω μπορούμε να φτιάξουμε σύνθετους
Εισαγωγή στον Προγραμματισμό
Εισαγωγή στον Προγραμματισμό Έλεγχος Δημήτρης Μιχαήλ Τμήμα Πληροφορικής και Τηλεματικής Χαροκόπειο Πανεπιστήμιο Ακ. Έτος 2012-2013 Σχεσιακοί Τελεστές και Ισότητας Ένα πρόγραμμα εκτός από αριθμητικές πράξεις
Προσπέλαση κοινών πόρων Πρωτόκολλα ελέγχου αμοιβαίου αποκλεισμού
Λειτουργικά Συστήματα Πραγματικού Χρόνου 2006-07 Προσπέλαση κοινών πόρων Πρωτόκολλα ελέγχου αμοιβαίου αποκλεισμού Μ.Στεφανιδάκης Κοινοί πόροι Κοινοί (διαμοιραζόμενοι) πόροι με μία η περισσότερες μονάδες
Ορισµός Νήµα (thread) είναι µια ακολουθιακή ροή ελέγχου (δηλ. κάτι που έχει αρχή, ακολουθία εντολών και τέλος) σ ένα
ΝΗΜΑΤΑ ΣΤΗ JAVA (1) Ορισµός Νήµα (thread) είναι µια ακολουθιακή ροή ελέγχου (δηλ. κάτι που έχει αρχή, ακολουθία εντολών και τέλος) σ ένα πρόγραµµα. Αιτία Η δυνατότητα αποµόνωσης (ή αυτονόµησης) κάποιων
Διάλεξη Εισαγωγή στη Java, Μέρος Γ
Τμήμα Πληροφορικής και Τηλεπικοινωνιών Ανάπτυξη Λογισμικού για Δίκτυα και Τηλεπικοινωνίες Χειμερινό Εξάμηνο 2017-2018 Διάλεξη Εισαγωγή στη Java, Μέρος Γ Νήματα (Threads) στην Java Συγχρονισμός Producer-Consumer
Αντικειμενοστρεφής Προγραμματισμός
ΑΡΙΣΤΟΤΕΛΕΙΟ ΠΑΝΕΠΙΣΤΗΜΙΟ ΘΕΣΣΑΛΟΝΙΚΗΣ ΑΝΟΙΚΤΑ ΑΚΑΔΗΜΑΙΚΑ ΜΑΘΗΜΑΤΑ Αντικειμενοστρεφής Προγραμματισμός Ενότητα 13: Ταυτόχρονος Προγραμματισμός Γρηγόρης Τσουμάκας, Επικ. Καθηγητής Άδειες Χρήσης Το παρόν
ΠΛΕ- 074 Αρχιτεκτονική Υπολογιστών 2
ΠΛΕ- 074 Αρχιτεκτονική Υπολογιστών 2 Πολυπύρηνοι επεξεργαστές, μέρος 2 Αρης Ευθυμίου Πηγές διαφανειών: συνοδευτικές διαφάνειες αγγλικης εκδοσης του βιβλιου Cache coherence & scalability! Τα πρωτόκολλα
Κρίσιμη Περιοχή Υπό Συνθήκη (Conditional Critical Regions) Ταυτόχρονος Προγραμματισμός 1
Κρίσιμη Περιοχή Υπό Συνθήκη (onditional ritical Regions) Ταυτόχρονος Προγραμματισμός 1 lalis@inf.uth.gr Πέρα από ελεγκτές Ο ελεγκτής είναι χρήσιμο εργαλείο συγχρονισμού παρέχει στον προγραμματιστή εγγυημένο
ΕΘΝΙΚΟ ΜΕΤΣΟΒΙΟ ΠΟΛΥΤΕΧΝΕΙΟ ΣΧΟΛΗ ΗΛΕΚΤΡΟΛΟΓΩΝ ΜΗΧΑΝΙΚΩΝ ΚΑΙ ΜΗΧΑΝΙΚΩΝ ΥΠΟΛΟΓΙΣΤΩΝ ΤΟΜΕΑΣ ΤΕΧΝΟΛΟΓΙΑΣ ΠΛΗΡΟΦΟΡΙΚΗΣ ΚΑΙ ΥΠΟΛΟΓΙΣΤΩΝ
ΕΘΝΙΚΟ ΜΕΤΣΟΒΙΟ ΠΟΛΥΤΕΧΝΕΙΟ ΣΧΟΛΗ ΗΛΕΚΤΡΟΛΟΓΩΝ ΜΗΧΑΝΙΚΩΝ ΚΑΙ ΜΗΧΑΝΙΚΩΝ ΥΠΟΛΟΓΙΣΤΩΝ ΤΟΜΕΑΣ ΤΕΧΝΟΛΟΓΙΑΣ ΠΛΗΡΟΦΟΡΙΚΗΣ ΚΑΙ ΥΠΟΛΟΓΙΣΤΩΝ ΕΡΓΑΣΤΗΡΙΟ ΥΠΟ ΛΟ ΓΙ ΣΤΙ ΚΩΝ ΣΥΣΤΗΜΑΤΩΝ www. c sl a b. ec e. n t ua. gr
Αμοιβαίος αποκλεισμός
Αμοιβαίος αποκλεισμός 1. Εισαγωγή 2. Κρίσιμα τμήματα (Critical Sections) 3. Υλοποίηση του αμοιβαίου αποκλεισμού I. Προσεγγίσεις λογισμικού II. Υποστήριξη εκ μέρους του υλικού III. Σηματοφορείς 4. Κλασσικά
Διάλεξη 8: Πρόβλημα Αμοιβαίου Αποκλεισμού. ΕΠΛ 432: Κατανεμημένοι Αλγόριθμοι
Διάλεξη 8: Πρόβλημα Αμοιβαίου Αποκλεισμού ΕΠΛ 432: Κατανεμημένοι Αλγόριθμοι Τι θα δούμε σήμερα Μοντέλο Κοινόχρηστης Μνήμης Αλγόριθμοι Αμοιβαίου Αποκλεισμού με Ισχυρούς Καταχωρητές ΕΠΛ432: Κατανεµηµένοι
Parallel Architectures
Parallel Architectures Memory Consistency + Synchronization Figures, examples από 1. Transactional Memory, D. Wood, Lecture Notes in ACACES 2009 2. Krste Asanović s Lecture Notes, University of California,
Διάλεξη 08: Λίστες ΙΙ Κυκλικές Λίστες
ΕΠΛ231 Δομές Δεδομένων και Αλγόριθμοι 1 Διάλεξη 08: Λίστες ΙΙ Κυκλικές Λίστες Στην ενότητα αυτή θα μελετηθούν τα εξής επιμέρους θέματα: - Κυκλικές Απλά Συνδεδεμένες Λίστες - Κυκλικές Διπλά Συνδεδεμένες
Δομές Δεδομένων & Αλγόριθμοι
Ουρές Ουρές Περίληψη Η ΟυράΑΔΤ Υλοποίηση με κυκλικό πίνακα Αυξανόμενη Ουρά βασισμένη σε πίνακα Interface ουράς στην C++ Η Ουρά ADT Η ΑΔΤ Ουρά αποθηκεύει αυθαίρετα αντικείμενα Οι εισαγωγές και διαγραφές
Διάλεξη 22: Δυαδικά Δέντρα. Διδάσκων: Παναγιώτης Ανδρέου
Διάλεξη 22: Δυαδικά Δέντρα Στην ενότητα αυτή θα μελετηθούν τα εξής επιμέρους θέματα: - Δυαδικά Δένδρα - Δυαδικά Δένδρα Αναζήτησης - Πράξεις Εισαγωγής, Εύρεσης Στοιχείου, Διαγραφής Μικρότερου Στοιχείου
Διάλεξη 06: Συνδεδεμένες Λίστες & Εφαρμογές Στοιβών και Ουρών
ΕΠΛ231 Δομές Δεδομένων και Αλγόριθμοι 1 Διάλεξη 06: Συνδεδεμένες Λίστες & Εφαρμογές Στοιβών και Ουρών Στην ενότητα αυτή θα μελετηθούν τα εξής επιμέρους θέματα: - Υλοποίηση ΑΤΔ με Συνδεδεμένες Λίστες -
Προβλήματα ταυτόχρονης εκτέλεσης (για νήματα με κοινή μνήμη)
Προβλήματα ταυτόχρονης εκτέλεσης (για νήματα με κοινή μνήμη) ΙΙΙ 1 lalis@inf.uth.gr Υποθέσεις εργασίας Νήματα/διεργασίες με κοινή μνήμη Αυτόματη διακοπή/εναλλαγή νημάτων/διεργασιών (π.χ. πάνω από 1 CPU
Προγραμματισμός Ι (HY120)
Προγραμματισμός Ι (HY20) # μνήμη & μεταβλητές πρόγραμμα & εκτέλεση Ψηφιακά δεδομένα, μνήμη, μεταβλητές 2 Δυαδικός κόσμος Οι υπολογιστές είναι δυαδικές μηχανές Όλη η πληροφορία (δεδομένα και κώδικας) κωδικοποιείται
Πανεπιστήμιο Θεσσαλίας Τμήμα Ηλεκτρολόγων Μηχανικών & Μηχανικών Υπολογιστών Τμήμα Πληροφορικής
Πανεπιστήμιο Θεσσαλίας Τμήμα Ηλεκτρολόγων Μηχανικών & Μηχανικών Υπολογιστών Τμήμα Πληροφορικής Άσκηση : Λυμένες Ασκήσεις Έστω ένα σύστημα μνήμης, στο οποίο έχουμε προσθέσει μια κρυφή μνήμη θυμάτων 6 θέσεων
Εισαγωγή στον Αντικειμενοστρεφή Προγραμματισμό Διάλεξη #15
Οι βασικές έννοιες που θα καλύψουμε Ομαδοποίηση αντικειμένων Εισαγωγή στις συλλογές Γενικές κλάσεις Iterators Συλλογές (ειδικά την ArrayList) Συνεχίζουμε την αναφορά στο θέμα της αφαίρεσης (abstraction)
ΠΛΗΡΟΦΟΡΙΚΗ ΙΙ (JAVA) 11/3/2008
ΠΛΗΡΟΦΟΡΙΚΗ ΙΙ (JAVA) 11/3/2008 Κατασκευαστές (Constructors) Ειδικός τύπος μεθόδων, οι οποίες: - είναι public και έχουν το ίδιο όνομα με αυτό της κλάσης - χρησιμοποιούνται για να αρχικοποιήσουν κάποιες
Προβλήματα ταυτόχρονης εκτέλεσης (για νήματα με κοινή μνήμη)
Προβλήματα ταυτόχρονης εκτέλεσης (για νήματα με κοινή μνήμη) ΙΙΙ 1 lalis@inf.uth.gr Υποθέσεις εργασίας Νήματα/διεργασίες με κοινή μνήμη Αυτόματη διακοπή/εναλλαγή νημάτων/διεργασιών (π.χ. πάνω από 1 CPU
Δομές Δεδομένων & Ανάλυση Αλγορίθμων. 3ο Εξάμηνο. Ουρά (Queue) Υλοποίηση της με τη βοήθεια πίνακα. http://aetos.it.teithe.gr/~demos/teaching_gr.
Δομές Δεδομένων & Ανάλυση Αλγορίθμων 3ο Εξάμηνο Ουρά (Queue) Υλοποίηση της με τη βοήθεια πίνακα http://aetos.it.teithe.gr/~demos/teaching_gr.html Δημοσθένης Σταμάτης Τμήμα Μηχανικών Πληροφορικής ATEI ΘΕΣΣΑΛΟΝΙΚΗΣ
Διάλεξη 9: Αλγόριθμοι Αμοιβαίου Αποκλεισμού με τη χρήση μεταβλητών Ανάγνωσης/Εγγραφής. ΕΠΛ 432: Κατανεμημένοι Αλγόριθμοι
Διάλεξη 9: Αλγόριθμοι Αμοιβαίου Αποκλεισμού με τη χρήση μεταβλητών Ανάγνωσης/Εγγραφής ΕΠΛ 432: Κατανεμημένοι Αλγόριθμοι Τι θα δούμε σήμερα Αλγόριθμος Ψησταριάς (Bakery Algorithm) Αλγόριθμος 2- επεξεργαστών
Προβλήματα ταυτόχρονης εκτέλεσης (για νήματα με κοινή μνήμη)
Προβλήματα ταυτόχρονης εκτέλεσης (για νήματα με κοινή μνήμη) ΙΙΙ 1 lalis@inf.uth.gr Υποθέσεις εργασίας Νήματα/διεργασίες με κοινή μνήμη Αυτόματη διακοπή/εναλλαγή νημάτων/διεργασιών (π.χ. πάνω από 1 CPU
Κατανεμημένα Συστήματα: Θεωρία και Προγραμματισμός. Ενότητα # 8: Ταυτοχρονισμός και νήματα Διδάσκων: Γεώργιος Ξυλωμένος Τμήμα: Πληροφορικής
Κατανεμημένα Συστήματα: Θεωρία και Προγραμματισμός Ενότητα # 8: Ταυτοχρονισμός και νήματα Διδάσκων: Γεώργιος Ξυλωμένος Τμήμα: Πληροφορικής Χρηματοδότηση Το παρόν εκπαιδευτικό υλικό έχει αναπτυχθεί στα
Συγχρονισμός. Συστήματα Παράλληλης Επεξεργασίας 9ο εξάμηνο ΣΗΜΜΥ ακ. έτος CSLab. Κορνήλιος Κούρτης
Συγχρονισμός Συστήματα Παράλληλης Επεξεργασίας 9ο εξάμηνο ΣΗΜΜΥ ακ. έτος 2009-2010 CSLab National Technical University of Athens Κορνήλιος Κούρτης kkourt@cslab.ece.ntua.gr Εργαστήριο Υπολογιστικών Συστημάτων
Διάλεξη 08: Λίστες ΙΙ Κυκλικές Λίστες
ΕΠΛ231 Δομές Δεδομένων και Αλγόριθμοι 1 Διάλεξη 0: Λίστες ΙΙ Κυκλικές Λίστες Στην ενότητα αυτή θα μελετηθούν τα εξής επιμέρους θέματα: - Κυκλικές Απλά Συνδεδεμένες Λίστες - Κυκλικές Διπλά Συνδεδεμένες
Μάθημα 4 ο. Κρίσιμα Τμήματα και Αμοιβαίος Αποκλεισμός
Μάθημα 4 ο Κρίσιμα Τμήματα και Αμοιβαίος Αποκλεισμός Εισαγωγή Σκοπός του μαθήματος αυτού είναι να εξηγήσει την έννοια του κρίσιμου τμήματος σε μία διεργασία και να δείξει τη λύση για ένα απλό πρόβλημα
Παράλληλος προγραμματισμός: Σχεδίαση παράλληλων προγραμμάτων
Εθνικό Μετσόβιο Πολυτεχνείο Σχολή Ηλεκτρολόγων Μηχ. και Μηχανικών Υπολογιστών Εργαστήριο Υπολογιστικών Συστημάτων Παράλληλος προγραμματισμός: Σχεδίαση παράλληλων προγραμμάτων 9 ο Εξάμηνο Σχεδιασμός παράλληλων
Καρακασίδης Αλέξανδρος Καστίδου Γεωργία Παπαφώτη Μαρία Πέτσιος Κων/νος Στέφανος Σαλτέας Καλογεράς Παναγιώτης. Threads in Java ΝΗΜΑΤΑ ΣΤΗ JAVA
Καρακασίδης Αλέξανδρος Καστίδου Γεωργία Παπαφώτη Μαρία Πέτσιος Κων/νος Στέφανος Σαλτέας Καλογεράς Παναγιώτης Threads in Java ΝΗΜΑΤΑ ΣΤΗ JAVA 1. Εισαγωγή Τι είναι Νήµα; Κάθε νήµα εκτέλεσης είναι ουσιαστικά
ΠΛΗ111. Ανοιξη 2005. Μάθηµα 3 ο. Συνδεδεµένες Λίστες. Τµήµα Ηλεκτρονικών Μηχανικών και Μηχανικών Υπολογιστών Πολυτεχνείο Κρήτης
ΠΛΗ111 οµηµένος Προγραµµατισµός Ανοιξη 2005 Μάθηµα 3 ο Συνδεδεµένες Λίστες Τµήµα Ηλεκτρονικών Μηχανικών και Μηχανικών Υπολογιστών Πολυτεχνείο Κρήτης Ανασκόπηση ΟΑΤ λίστα Ακολουθιακή λίστα Συνδεδεµένη λίστα
Διασυνδεδεμένες Δομές. Λίστες. Προγραμματισμός II 1
Διασυνδεδεμένες Δομές Λίστες Προγραμματισμός II 1 lalis@inf.uth.gr Διασυνδεδεμένες δομές Η μνήμη ενός πίνακα δεσμεύεται συνεχόμενα η πρόσβαση στο i-οστό στοιχείο είναι άμεση καθώς η διεύθυνση του είναι
Θοδωρής Ανδρόνικος Τμήμα Πληροφορικής, Ιόνιο Πανεπιστήμιο
Θοδωρής Ανδρόνικος Τμήμα Πληροφορικής, Ιόνιο Πανεπιστήμιο Για το μάθημα «Διαχείριση Λειτουργικών Συστημάτων» του ακαδημαϊκού έτους 2015 2016, το προτεινόμενο σύγγραμμα είναι το: Operating Systems: Internals
CSLab National Technical University of Athens
http://www.cslab.ece.ntua.gr/courses/os CSLab National Technical University of Athens #define NEXT(x) ((x + 1) % N) item_t buffer[n]; int in=0, out=0, count=0; #define NEXT(x) ((x + 1) % N) item_t buffer[n];
Κατανεμημένα Συστήματα με Java. Ενότητα # 4: Αμοιβαίος αποκλεισμός Διδάσκων: Γεώργιος Ξυλωμένος Τμήμα: Πληροφορικής
Κατανεμημένα Συστήματα με Java Ενότητα # 4: Αμοιβαίος αποκλεισμός Διδάσκων: Γεώργιος Ξυλωμένος Τμήμα: Πληροφορικής Χρηματοδότηση Το παρόν εκπαιδευτικό υλικό έχει αναπτυχθεί στα πλαίσια του εκπαιδευτικού
Προβλήματα Συγχρονισμού (με ελεγκτή) Ταυτόχρονος Προγραμματισμός 1
Προβλήματα Συγχρονισμού (με ελεγκτή) Ταυτόχρονος Προγραμματισμός 1 lalis@inf.uth.gr Υλοποίηση σηματοφόρων Οι σηματοφόροι είναι ένας ΑΤΔ με συγκεκριμένες λειτουργίες πρόσβασης Μπορεί να υλοποιηθούν με «φυσικό»
Οι λίστες, χάνοντας τα πλεονεκτήματα των πινάκων, λύνουν προβλήματα που παρουσιάζουν οι πίνακες
Δομές δεδομένων Πίνακες Οι πίνακες είναι το πιο απλό «μέσο» αποθήκευσης ομοειδούς πληροφορίας. Χρησιμοποιούν ακριβώς όση μνήμη χρειάζεται για την αποθήκευση της πληροφορίας Επιτρέπουν την προσπέλαση άμεσα
Διεργασίες και Νήματα (2/2)
Εθνικό Μετσόβιο Πολυτεχνείο Σχολή Ηλεκτρολόγων Μηχ. και Μηχανικών Υπολογιστών Εργαστήριο Υπολογιστικών Συστημάτων Διεργασίες και Νήματα (2/2) Λειτουργικά Συστήματα Υπολογιστών 7ο Εξάμηνο, 2016-2017 Νήματα
Δομές Δεδομένων - Εργαστήριο 5. Ουρές Προτεραιότητας
Ουρές Προτεραιότητας Ουρά Προτεραιότητας (Priority Queue) Μια συλλογή αντικειμένων που χαρακτηρίζονται από μια συγκρίσιμη προτεραιότητα. Έχει την λογική εικόνα μιας δομής δεδομένων όπου, αντικείμενα εισέρχονται
Κλάσεις στη Java. Παύλος Εφραιμίδης. Java Κλάσεις στη Java 1
Κλάσεις στη Java Παύλος Εφραιμίδης Java Κλάσεις στη Java 1 Κλάσεις στην Java Θα δούμε τη διαδικασία δημιουργίας μιας κλάσης Θα υλοποιήσουμε μια κλάση για τη Δομή Δεδομένων Stack Java Κλάσεις στη Java 2
Από τη UML στον Κώδικα. Μέρος Α
Από τη UML στον Κώδικα Μέρος Α περιεχόμενα παρουσίασης Κλάσεις Ισότητα αντικειμένων Μονόδρομες συσχετίσεις με πολλαπλότητα «ένα» Μονόδρομες συσχετίσεις με πολλαπλότητα «πολλά» Συλλογές από το σχέδιο στον
lab13grades Άσκηση 2 -Σωστά απελευθερώνετε ολόκληρη τη λίστα και την κεφαλή
ΑΕΜ ΒΑΘΜΟΣ ΣΧΟΛΙΑ 00497 -Δεν ελέγχετε αν η createlist εκτελλέστικε σωστά και δεν τερµατίζετε το πρόγραµµα σε διαφορετική -Σωστά βρίσκετε το σηµείο στο οποίο πρέπει να προστεθεί ο κόµβος. -Σωστά τερµατίζετε
Τύποι Δεδομένων και Απλές Δομές Δεδομένων. Παύλος Εφραιμίδης V1.0 ( )
Τύποι Δεδομένων και Απλές Δομές Δεδομένων Παύλος Εφραιμίδης V1.0 (2014-01-13) Απλές Δομές Δεδομένων Στην ενότητα αυτή θα γνωρίσουμε ορισμένες απλές Δομές Δεδομένων και θα τις χρησιμοποιήσουμε για την αποδοτική
Κλάσεις στη Java. Στοίβα - Stack. Δήλωση της κλάσης. ΗκλάσηVector της Java. Ηκλάση Stack
Κλάσεις στην Java Κλάσεις στη Java Παύλος Εφραιμίδης Θα δούμε τη διαδικασία δημιουργίας μιας κλάσης Θα υλοποιήσουμε μια κλάση για τη Δομή Δεδομένων Stack Java Κλάσεις στη Java 1 Java Κλάσεις στη Java 2
ΠΛΗ111. Ανοιξη Μάθηµα 5 ο. Ουρά. Τµήµα Ηλεκτρονικών Μηχανικών και Μηχανικών Υπολογιστών Πολυτεχνείο Κρήτης
ΠΛΗ οµηµένος Προγραµµατισµός Ανοιξη 5 Μάθηµα 5 ο Ουρά Τµήµα Ηλεκτρονικών Μηχανικών και Μηχανικών Υπολογιστών Πολυτεχνείο Κρήτης Ανασκόπηση Αφηρηµένος Τύπος εδοµένων Ουρά Υλοποίηση µε Κυκλικό Πίνακα Υλοποίηση
Υ- 01 Αρχιτεκτονική Υπολογιστών Πολυεπεξεργαστές, 2ο μέρος
Υ- 01 Αρχιτεκτονική Υπολογιστών Πολυεπεξεργαστές, 2ο μέρος Αρης Ευθυμίου Το σημερινό μάθημα! Cache coherence directory protocols! Memory consistency! MulG- threading 2 Cache coherence & scalability! Τα
Εργαστήριο Λειτουργικών Συστημάτων 8o εξάμηνο, Ροή Υ, ΗΜΜΥ
ΕΘΝΙΚΟ ΜΕΤΣΟΒΙΟ ΠΟΛΥΤΕΧΝΕΙΟ Σχολή Ηλεκτρολόγων Μηχανικών και Μηχανικών Υπολογιστών Εργαστήριο Λειτουργικών Συστημάτων 8o εξάμηνο, Ροή Υ, ΗΜΜΥ Σχεδιασμός και υλοποίηση υποδομής σημείωσης διεργασιών στον