Πώς αποθηκεύονται οι αριθμοί σε ένα ηλεκτρονικό κύκλωμα που καταλαβαίνει μόνο 0 και 1; Παραπάνω είδαμε πως περιγράφονται οι ακέραιοι (1, 2, 3, ...) με τη βοήθεια πολλών λαμπτήρων, αλλά τι γίνεται με τον αριθμό 3,14 (τυχαία τον επέλεξα, δεν έχει να κάνει τίποτε με το π). Εδώ τα πράματα γίνονται λίγο πιο πολύπλοκα και γι'αυτό καθιερώθηκαν κάποια πρότυπα που διευκολύνουν τη ζωή των υπολογιστών. Καταρχήν θα γράψουμε τον αριθμο 3,14 ως εξής: + 0,314 * 10**1. (Το σύμβολο ** δηλώνει εκθέτη επηρεασμένος από τη FORTRAN, δηλαδή 10**1=10, 10**2=100, 10**3=1000 κ.ο.κ) Το πρόσημο μπορεί να είναι + ή -, αρα μπορεί να περιγραφεί με μία λάμπα, σβηστή/ανοιχτή. Το 0, αποφασίσαμε να είναι το ίδιο για όλους τους αριθμούς, άρα δε χρειάζεται να το αποθηκεύσουμε. Έπειτα μετατρέπουμε τον αριθμό 314 σε δυαδική μορφή, όπως περιγράφεται παραπάνω, δηλ. 100111010. Το 10** είναι κι αυτό μέσα στην τυποποίησή μας. Και μετά αποθηκεύουμε το 1. Έτσι χρειαζόμαστε μία λάμπα για το πρόσημο, ένα σύνολο από λάμπες για τον αριθμό μετά την υποδιαστολή (για συντομία θα το λέμε mantissa), και μετά σύνολο από λάμπες για τον εκθέτη. Όσο μεγαλύτερο είναι τα σύνολο (η μνήμη δηλαδή) για τον αριθμό μετά την υποδιαστολή τόση μεγαλύτερη ακρίβεια μπορούμε να επιτυχουμε. Όσο μεγαλύτερο είναι τα σύνολο (η μνήμη δηλαδή) για τον εκθέτη τόσο μεγαλύτερους αριθμούς μπορούμε να αποθηκεύσουμε. Αυτή είναι ουσιαστικά η διαφορά μεταξύ float και double στη C αλλά και σε πολλές γλώσσες προγραμματισμού.
Πώς κάνουμε τώρα πράξεις με αυτό το πολύπλοκο κατασκεύασμα; Όπως θα την κάναμε και με το χέρι. Άς πάρουμε την πρόσθεση. Πρώτα θα συγκρίναμε τον εκθέτη, έπειτα θα μετακινούσαμε την υποδιαστολή στην κατάλληλ θέση, θα προσθέταμε και τέλος θα φέρναμε το αποτέλεσμα στην τελική μορφή. Αυτό κάνει και ο επεξεργαστής όταν έχει να προσθέσει δύο αριθμούς. Η όλη διαδικασία λέγεται αναφέρεται ως floating point arithemic. Και αυτός είναι ουσιαστικά ο τρόπος να συγκρίνουμε δύο επεξεργαστές. Πόσες πράξεις μπορούνε να κάνουν το δευτερόλεπτο (FLOPS=Floating Point Operations Per Second)
Ας υποθέσουμε τώρα ότι έχουμε μια ταινία (μαγνητική όπως οι παλιές), η οποία είναι χωρισμένη σε τετραγωνα. Σε κάθε τετράγωνο χωράει ένας δυαδικός αριθμός με 4 ψηφία, ας πούμε. Τότε ο αριθμός παραπάνω θα χρειάζεται ένα τετραγωνο για την αποθήκευση του προσήμου (0000), 6 τετράγωνα για την αποθήκευση της mantissa (000 0000 0000 0001 0011 1010) και ένα τετράγωνα για τον εκθετη (0001), σύνολο 8. Αν έχουμε δηλαδή ένα array (a[10] στη C) με 10 τέτοιους αριθμούς, τότε αυτοί θα αποθηκευτούν διαδοχικά στα 8x10 τετράγωνα, θέσεις μνήμης δηλαδή.
Mέχρι στιγμής προϋποθέτουμε ότι οι δύο αριθμοί βρίσκονται στη μνήμη. Σε ποιά μνήμη όμως; Καταρχήν υπάρχει ο σκληρός δίσκος, μπορεί να χρησιμεύσει ως εικονική μνήμη (virtual memory) αλλά είναι πολύ αργός. Έπειτα είναι η RAM, ένα ενδιάμεσο βήμα με μικρότερη χωρητικότητα, αλλά ελαφρώς πιο γρήγορη από το σκληρό δισκό (ναι καλά διαβάσατε, ελαφρώς πιο γρήγορη σε σχέση με αυτό που ακολουθεί). Έπειτα έχουμε την cache (υπάρχει σε δύο επίπεδα L2 και L1) η οποία είναι σαφώς γρηγορότερη αλλά και μικρότερα. Τέλος υπάρχει το registry, που είναι ουσιαστικά ενσωματωμένο στον επεξεργαστή και χωράει ίσα ίσα μερικές μεταβητές (βλ. register της C).
Περνάμε τώρα στο cache mapping. To παραπάνω array χωράει στη μνήμη RAM χωρίς κανένα πρόβλημα. Αλλά ας υποθέσουμε (τα νούμερα εδώ είναι για λόγους του παραδείγματος μόνο, στην πραγματικότητα είναι μεγαλύτερα) ότι η μνήμη cache έχει μόνο 40 τετράγωνα. Tότε αυτό που θα κάνει ο υπολογιστής, σε ένα βρόγχο για παράδειγμα, είναι να φορτώσει τα 20 πρώτα μέλη του array μας και μετά τα επόμενα 20. Ένα πρόγραμμα αρχίζει και γίνεται αργό όταν δεν είναι καλά σχεδιασμένο και την ίδια στιγμή χρειάζονται τα a[3] και a[8] για μία διεργασία.
Αν αριθμήσουμε την ταινία μας από 1 μέχρι 80 και πάει λέγοντας, τότε μπορούμε να αναθέσουμε σε κάθε αριθμό και μία διεύθυνση. Το τρίτο στοιχείο του array ξεκινάει στη θέση 17 (2*8+1) στο δυαδικό 0001 0001. Αν αποθηκεύσουμε αυτόν τον αριθμό στα τετράγωνα ας πούμε 126-127 τότε έχουμε τη διεύθυνση του a[3]. Αυτό το ονομάζουμε δείκτη (pointer) γιατί δείχνει στη διεύθυνση κάποιου άλλου στοιχείου. (Να με συγχωρέσουν οι προγαμματιστές C για τον "ανορθόδοξο" τρόπο αρίθμησης)
No comments:
Post a Comment