Έχω μια απορία για την υλοποίηση της lock.Δυστυχώς μετά από αρκετές προσομοιώσεις κατάλαβα ότι κάτι πήγαινε λάθος με την υλοποίηση μου και το επιβεβαίωσα με το DDEBUG του locks_scalability.Το πρόβλημα είναι ότι ακόμα δεν είμαι σίγουρος γιατί είναι λάθος η υλοποίηση και δεν μπορώ πλέον να αντιληφθώ πως θα κάνουμε χρήση της compare and swap (προσπάθησα να βρω εναλλακτικές εντολές του gcc αλλά αν και δούλευαν στο debug έλεγαν ότι έχουν κάποιους περιορισμούς οπότε τις άφησα) Η υλοποίηση μου βασιζόταν στο εξής : Η compare and swap κάνει swap μόνο όταν το lock είναι oldval αλλά εμείς στο test and set θέλουμε να κάνουμε set κάθε φορά έτσι κι αλλιώς οπότε σκέφτηκα να του δώσω σαν oldval την ίδια την τιμή του lock δηλαδή *lock. Το μόνο που μπορώ να σκεφτώ είναι ότι το *lock παίρνει την τιμή από την cache ή κάποια μη τρέχουσα τιμή(αν και αμφιβάλλω αφού δηλώνουμε το lock volatile) και συγκρίνεται με την πρόσφατη τιμή στη μνήμη που είναι διαφορετική.Τότε αν είναι locked στην cache και unlocked στη μνήμη τότε τερματίζει η acquire lock αλλά δεν κλειδώνουμε με αποτέλεσμα ο επόμενος να το βρίσκει ξεκλείδωτο οπότε να μπαίνει και αυτός στην κρίσιμη περιοχή. Δεν ξέρω αν η παραπάνω είναι η σωστή εξήγηση οπότε μια επιβεβαίωση/διόρθωση είναι ευπρόσδεκτη. Αυτό που δεν καταλαβαίνω είναι πώς θα μετατρέψω την compare and swap σε μια απλή ατομική εντολή set.Ίσως μπορεί κάποιος να δώσει καμιά ιδέα Επίσης μια ακόμη ερώτηση είναι αν το release πρέπει να γίνει και αυτό ατομικά ή όχι και αν ναι γιατί; Ευχαριστώ πολύ εκ των προτέρων, Λάμπρος Φλόκας
Καλησπέρα,
On 06/30/2013 11:51 AM, Lambros Flokas wrote:
Έχω μια απορία για την υλοποίηση της lock.Δυστυχώς μετά από αρκετές προσομοιώσεις κατάλαβα ότι κάτι πήγαινε λάθος με την υλοποίηση μου και το επιβεβαίωσα με το DDEBUG του locks_scalability.Το πρόβλημα είναι ότι ακόμα δεν είμαι σίγουρος γιατί είναι λάθος η υλοποίηση και δεν μπορώ πλέον να αντιληφθώ πως θα κάνουμε χρήση της compare and swap (προσπάθησα να βρω εναλλακτικές εντολές του gcc αλλά αν και δούλευαν στο debug έλεγαν ότι έχουν κάποιους περιορισμούς οπότε τις άφησα) Η υλοποίηση μου βασιζόταν στο εξής : Η compare and swap κάνει swap μόνο όταν το lock είναι oldval αλλά εμείς στο test and set θέλουμε να κάνουμε set κάθε φορά έτσι κι αλλιώς οπότε σκέφτηκα να του δώσω σαν oldval την ίδια την τιμή του lock δηλαδή *lock.
Παρόλο που δε φαίνεται από τα semantics της __sync_val_compare_and_swap στην εκφώνηση, η αλήθεια είναι ότι σε *κάθε* κλήση της, ανεξαρτήτως των τρεχόντων περιεχομένων του ptr, εκτελείται μια "ακριβή" ατομική εντολή που γράφει πάνω στο bus. Θεωρείτε δηλαδή ότι σε κάθε περίπτωση γίνεται εγγραφή της μνήμης, όπως κάνει και η test-and-set.
Όπως και να 'χει, η TTAS υλοποίηση θα πρέπει να διαφοροποιηθεί από την TAS στο ότι κάνει απλά και "φθηνά" reads στην lock μεταβλητή μέσα σε ένα loop, και μόνο όταν αυτή *φανεί* ξεκλείδωτη επιχειρεί το "ακριβό" atomic operation.
Ελπίζω να βοήθησα.
N.
Ευχαριστώ πολύ.Μετά από αρκετή ώρα και ψάξιμο βρήκα την λύση (η οποία την είχα σκεφτεί από την αρχή αλλά λόγω της παρανόησης που παρουσίασες νόμιζα ότι ήταν λάθος) αλλά τώρα κατάλαβα ακόμα καλύτερα την διαφορά στην απόδοση ttas και tas.
2013/7/1 Nikos Anastopoulos anastop@cslab.ece.ntua.gr
Καλησπέρα,
On 06/30/2013 11:51 AM, Lambros Flokas wrote:
Έχω μια απορία για την υλοποίηση της lock.Δυστυχώς μετά από αρκετές προσομοιώσεις κατάλαβα ότι κάτι πήγαινε λάθος με την υλοποίηση μου και το επιβεβαίωσα με το DDEBUG του locks_scalability.Το πρόβλημα είναι ότι ακόμα δεν είμαι σίγουρος γιατί είναι λάθος η υλοποίηση και δεν μπορώ πλέον να αντιληφθώ πως θα κάνουμε χρήση της compare and swap (προσπάθησα να βρω εναλλακτικές εντολές του gcc αλλά αν και δούλευαν στο debug έλεγαν ότι έχουν κάποιους περιορισμούς οπότε τις άφησα) Η υλοποίηση μου βασιζόταν στο εξής : Η compare and swap κάνει swap μόνο όταν το lock είναι oldval αλλά εμείς στο test and set θέλουμε να κάνουμε set κάθε φορά έτσι κι αλλιώς οπότε σκέφτηκα να του δώσω σαν oldval την ίδια την τιμή του lock δηλαδή *lock.
Παρόλο που δε φαίνεται από τα semantics της __sync_val_compare_and_swap στην εκφώνηση, η αλήθεια είναι ότι σε *κάθε* κλήση της, ανεξαρτήτως των τρεχόντων περιεχομένων του ptr, εκτελείται μια "ακριβή" ατομική εντολή που γράφει πάνω στο bus. Θεωρείτε δηλαδή ότι σε κάθε περίπτωση γίνεται εγγραφή της μνήμης, όπως κάνει και η test-and-set.
Όπως και να 'χει, η TTAS υλοποίηση θα πρέπει να διαφοροποιηθεί από την TAS στο ότι κάνει απλά και "φθηνά" reads στην lock μεταβλητή μέσα σε ένα loop, και μόνο όταν αυτή *φανεί* ξεκλείδωτη επιχειρεί το "ακριβό" atomic operation.
Ελπίζω να βοήθησα.
N.
advcomparch@lists.cslab.ece.ntua.gr