Κάποιες μέρες είναι διασκεδαστικό να βλέπεις το επίπεδο επιφάνειας της εμπειρίας υπολογιστών και άλλες μέρες είναι διασκεδαστικό να βυθίζεσαι κατευθείαν στις εσωτερικές λειτουργίες. Σήμερα ρίχνουμε μια ματιά στη δομή της μνήμης του υπολογιστή και πόσα πράγματα μπορείτε να τοποθετήσετε σε ένα RAM
Η σημερινή συνεδρία Ερωτήσεων & Απαντήσεων μας προσφέρει ευγενική προσφορά του SuperUser - μια υποδιαίρεση του Stack Exchange, μιας ομάδας ιστότοπων Q&A που βασίζεται στην κοινότητα.
Το ερώτημα
Ο αναγνώστης SuperUser Johan Smohan αντιμετωπίζει τον τρόπο με τον οποίο ο τύπος του επεξεργαστή και το μέγεθος της μνήμης συνεργάζονται για να δώσουν έναν συνολικό αριθμό διευθύνσεων. Αυτός γράφει:
Πόσες διευθύνσεις μνήμης μπορούμε να πάρουμε με έναν επεξεργαστή 32-bit και έναν RAM 1 GB και πόσες με έναν επεξεργαστή 64-bit;
Νομίζω ότι είναι κάπως έτσι:
1 GB ram διαιρούμενο με 32 bit 4 bit (?) Για να λάβετε τον αριθμό των διευθύνσεων μνήμης;
Διάβασα στη Βικιπαίδεια ότι 1 διευθύνσεις μνήμης έχει πλάτος 32 bit ή 4 οκτάδες (1 octet = 8 bit), σε σύγκριση με έναν επεξεργαστή 64 bit όπου 1 διευθύνσεις μνήμης ή 1 ακέραιος πλάτος 64 bit ή 8 οκτάδες. Αλλά δεν ξέρω αν το κατάλαβα σωστά.
Αυτά είναι τα είδη των ερωτήσεων που μπορούν να κρατήσουν ένα περίεργο geek τη νύχτα. Πόσες διευθύνσεις είναι διαθέσιμες σε καθένα από τα υποθετικά συστήματα του Johan;
Η απάντηση
Ο συνεργάτης της SuperUser Gronostaj προσφέρει κάποια εικόνα για το πώς διαιρείται και χρησιμοποιείται η μνήμη RAM:
Σύντομη απάντηση: Ο αριθμός των διαθέσιμων διευθύνσεων είναι ίσος με το μικρότερο από αυτές:
- Μέγεθος μνήμης σε byte
- Ο μεγαλύτερος ανυπόγραφος ακέραιος αριθμός που μπορεί να αποθηκευτεί στη λέξη μηχάνημα της CPU
Μεγάλη απάντηση και εξήγηση των παραπάνω:
Η μνήμη αποτελείται από byte (B). Κάθε byte αποτελείται από 8 bits (b).
1 B = 8 β1 GB μνήμης RAM είναι στην πραγματικότητα 1 GiB (gibibyte, όχι gigabyte). Η διαφορά είναι:
1 GB = 10 ^ 9 B = 1 000 000 000 B 1 GiB = 2 ^ 30 B = 1 073 741 824 ΒΚάθε byte μνήμης έχει τη δική του διεύθυνση, ανεξάρτητα από το πόσο μεγάλη είναι η λέξη της μηχανής CPU. Π.χ. Ο επεξεργαστής Intel 8086 ήταν 16-bit και αντιμετώπιζε τη μνήμη με byte, όπως και οι σύγχρονοι CPU 32-bit και 64-bit. Αυτή είναι η αιτία του πρώτου ορίου - δεν μπορείτε να έχετε περισσότερες διευθύνσεις από τα byte μνήμης.
Η διεύθυνση μνήμης είναι μόνο ένας αριθμός byte που πρέπει να παραλείψει η CPU από την αρχή της μνήμης για να φτάσει σε αυτήν που αναζητά.
- Για να αποκτήσετε πρόσβαση στο πρώτο byte πρέπει να παραλείψετε 0 byte, οπότε η διεύθυνση του πρώτου byte είναι 0.
- Για να αποκτήσετε πρόσβαση στο δεύτερο byte πρέπει να παραλείψετε 1 byte, οπότε η διεύθυνσή του είναι 1.
- (και ούτω καθεξής…)
- Για να αποκτήσετε πρόσβαση στο τελευταίο byte, η CPU παραλείπει 1073741823 byte, οπότε η διεύθυνσή της είναι 1073741823.
Τώρα πρέπει να ξέρετε τι σημαίνει πραγματικά το 32-bit. Όπως ανέφερα προηγουμένως, είναι το μέγεθος μιας μηχανικής λέξης.
Το word word είναι το μέγεθος της μνήμης που χρησιμοποιεί η CPU για τη συγκράτηση αριθμών (σε RAM, cache ή εσωτερικούς καταχωρητές) Η CPU 32-bit χρησιμοποιεί 32 bit (4 byte) για να κρατήσει τους αριθμούς. Οι διευθύνσεις μνήμης είναι επίσης αριθμοί, οπότε σε μια CPU 32-bit η διεύθυνση μνήμης αποτελείται από 32 bit.
Τώρα σκεφτείτε αυτό: εάν έχετε ένα bit, μπορείτε να αποθηκεύσετε δύο τιμές σε αυτό: 0 ή 1. Προσθέστε ένα ακόμη bit και έχετε τέσσερις τιμές: 0, 1, 2, 3. Σε τρία bit, μπορείτε να αποθηκεύσετε οκτώ τιμές : 0, 1, 2… 6, 7. Αυτό είναι στην πραγματικότητα ένα δυαδικό σύστημα και λειτουργεί έτσι:
Δυαδικό δεκαδικό 0 0000 1 0001 2 0010 3 0011 4 0100 5 0101 6 0110 7 0111 8 1000 9 1001 10 1010 11 1011 12 1100 13 1101 14 1110 15 1111Λειτουργεί ακριβώς όπως η συνήθης προσθήκη, αλλά το μέγιστο ψηφίο είναι 1, όχι 9. Το δεκαδικό 0 είναι
0000, τότε προσθέτετε 1 και παίρνετε0001, προσθέστε ένα για άλλη μια φορά και έχετε0010. Αυτό που συνέβη εδώ είναι σαν να έχουμε δεκαδικά09και προσθέτοντας ένα: αλλάζετε 9 σε 0 και αυξήστε το επόμενο ψηφίο.Από το παραπάνω παράδειγμα μπορείτε να δείτε ότι υπάρχει πάντα μια μέγιστη τιμή που μπορείτε να διατηρήσετε σε έναν αριθμό με σταθερό αριθμό bit - γιατί όταν όλα τα bit είναι 1 και προσπαθείτε να αυξήσετε την τιμή κατά 1, όλα τα bit θα γίνουν 0, σπάζοντας έτσι αριθμός. Ονομάζεται ακέραια υπερχείλιση και προκαλεί πολλά δυσάρεστα προβλήματα, τόσο για τους χρήστες όσο και για τους προγραμματιστές.
11111111 = 255 + 1 ----------- 100000000 = 0 (9 bits εδώ, έτσι 1 κόβεται)
- Για 1 bit η μεγαλύτερη τιμή είναι 1,
- 2 bits - 3,
- 3 bits - 7,
- 4 bits - 15
Ο μεγαλύτερος δυνατός αριθμός είναι πάντα 2 ^ N-1, όπου N είναι ο αριθμός bit. Όπως είπα προηγουμένως, μια διεύθυνση μνήμης είναι ένας αριθμός και έχει επίσης μια μέγιστη τιμή. Αυτός είναι ο λόγος για τον οποίο το μέγεθος της μηχανικής λέξης είναι επίσης ένα όριο για τον αριθμό των διαθέσιμων διευθύνσεων μνήμης - μερικές φορές η CPU σας δεν μπορεί να επεξεργαστεί αριθμούς αρκετά μεγάλους για να αντιμετωπίσει περισσότερη μνήμη.
Έτσι, σε 32 bit μπορείτε να διατηρήσετε αριθμούς από 0 έως 2 ^ 32-1, και αυτό είναι 4 294 967 295. Είναι κάτι παραπάνω από τη μεγαλύτερη διεύθυνση σε 1 GB RAM, οπότε στη συγκεκριμένη περίπτωση, το ποσό της μνήμης RAM θα είναι ο περιοριστικός παράγοντας.
Το όριο RAM για CPU 32-bit είναι θεωρητικά 4 GB (2 ^ 32) και για CPU 64-bit είναι 16 EB (exabytes, 1 EB = 2 ^ 30 GB). Με άλλα λόγια, η CPU 64-bit θα μπορούσε να απευθύνεται σε ολόκληρο το Διαδίκτυο… 200 φορές;) (εκτιμάται από WolframAlpha ).
Ωστόσο, σε πραγματικά λειτουργικά συστήματα 32-bit CPU μπορούν να αντιμετωπίσουν περίπου 3 GiB μνήμης RAM. Αυτό οφείλεται στην εσωτερική αρχιτεκτονική του λειτουργικού συστήματος - ορισμένες διευθύνσεις προορίζονται για άλλους σκοπούς. Μπορείτε να διαβάσετε περισσότερα για αυτό το λεγόμενο Φράγμα 3 GB στη Wikipedia . Μπορείτε να καταργήσετε αυτό το όριο με Επέκταση φυσικής διεύθυνσης .
Μιλώντας για τη διεύθυνση μνήμης, υπάρχουν λίγα πράγματα που πρέπει να αναφέρω: εικονική μνήμη , κατάτμηση και σελιδοποίηση .
Εικονική μνήμη
Όπως επεσήμανε ο @Daniel R Hicks σε μια άλλη απάντηση, τα λειτουργικά συστήματα χρησιμοποιούν εικονική μνήμη. Αυτό σημαίνει ότι οι εφαρμογές στην πραγματικότητα δεν λειτουργούν σε πραγματικές διευθύνσεις μνήμης, αλλά αυτές που παρέχονται από το λειτουργικό σύστημα.
Αυτή η τεχνική επιτρέπει στο λειτουργικό σύστημα να μεταφέρει ορισμένα δεδομένα από τη RAM σε ένα λεγόμενο Pagefile (Windows) ή Swap (* NIX). Ο σκληρός δίσκος έχει λίγα μεγέθη πιο αργό από τη μνήμη RAM, αλλά δεν είναι σοβαρό πρόβλημα για σπάνια προσπελάσιμα δεδομένα και επιτρέπει στο λειτουργικό σύστημα να παρέχει σε εφαρμογές περισσότερη μνήμη RAM από ό, τι πραγματικά έχετε εγκαταστήσει.
Σελιδοποίηση
Αυτό για το οποίο μιλούσαμε μέχρι τώρα ονομάζεται σχήμα επίπεδης αντιμετώπισης.
Το σελιδοποίηση είναι ένα εναλλακτικό σχήμα διευθυνσιοδότησης που επιτρέπει την αντιμετώπιση περισσότερης μνήμης που θα μπορούσατε κανονικά με μία λέξη μηχανής σε επίπεδο μοντέλο.
Φανταστείτε ένα βιβλίο γεμάτο με λέξεις 4 γραμμάτων. Ας υποθέσουμε ότι υπάρχουν 1024 αριθμοί σε κάθε σελίδα. Για να αντιμετωπίσετε έναν αριθμό, πρέπει να γνωρίζετε δύο πράγματα:
- Ο αριθμός της σελίδας στην οποία εκτυπώνεται αυτή η λέξη.
- Ποια λέξη σε αυτήν τη σελίδα είναι αυτή που αναζητάτε.
Έτσι ακριβώς οι σύγχρονες CPU x86 χειρίζονται μνήμη Χωρίζεται σε 4 σελίδες KiB (1024 λέξεις μηχανής η καθεμία) και αυτές οι σελίδες έχουν αριθμούς. (στην πραγματικότητα οι σελίδες μπορούν επίσης να έχουν μέγεθος 4 MiB ή 2 MiB ΠΑΕ ). Όταν θέλετε να απευθυνθείτε στο κελί μνήμης, χρειάζεστε τον αριθμό και τη διεύθυνση της σελίδας σε αυτήν τη σελίδα. Σημειώστε ότι κάθε κελί μνήμης αναφέρεται από ακριβώς ένα ζεύγος αριθμών, κάτι που δεν ισχύει για τμηματοποίηση.
Κατάτμηση
Λοιπόν, αυτό μοιάζει πολύ με τη σελιδοποίηση. Χρησιμοποιήθηκε στο Intel 8086, για να αναφέρουμε μόνο ένα παράδειγμα. Οι ομάδες διευθύνσεων ονομάζονται πλέον τμήματα μνήμης και όχι σελίδες. Η διαφορά είναι ότι τα τμήματα μπορούν να αλληλεπικαλύπτονται και αλληλεπικαλύπτονται πολύ. Για παράδειγμα, στο 8086 τα περισσότερα κελιά μνήμης ήταν διαθέσιμα από 4096 διαφορετικά τμήματα.
Ενα παράδειγμα:
Ας υποθέσουμε ότι έχουμε 8 byte μνήμης, όλα με μηδενικά εκτός από το 4ο byte που είναι ίσο με 255.
Εικόνα για μοντέλο επίπεδης μνήμης:
_____ | 0 | | 0 | | 0 | | 255 | | 0 | | 0 | | 0 | | 0 | -----Εικόνα για σελιδοποιημένη μνήμη με σελίδες 4 byte:
ΣΕΛΙΔΑ0 _____ | 0 | | 0 | | 0 | ΣΕΛΙΔΑ 1 | 255 | _____ ----- | 0 | | 0 | | 0 | | 0 | -----Εικόνα για τμηματοποιημένη μνήμη με τμήματα 4 byte μετατοπισμένα κατά 1:
SEG 0 _____ SEG 1 | 0 | _____ SEG 2 | 0 | | 0 | _____ SEG 3 | 0 | | 0 | | 0 | _____ SEG 4 | 255 | | 255 | | 255 | | 255 | _____ 5 SEG ----- | 0 | | 0 | | 0 | | 0 | _____ SEG 6 ----- | 0 | | 0 | | 0 | | 0 | _____ 7 SEG ----- | 0 | | 0 | | 0 | | 0 | _____ ----- | 0 | | 0 | | 0 | | 0 | ----- ----- ----- -----Όπως μπορείτε να δείτε, το 4ο byte μπορεί να αντιμετωπιστεί με τέσσερις τρόπους: (διεύθυνση από 0)
- Τμήμα 0, μετατόπιση 3
- Τμήμα 1, μετατόπιση 2
- Τμήμα 2, μετατόπιση 1
- Τμήμα 3, μετατόπιση 0
Είναι πάντα το ίδιο κελί μνήμης.
Σε πραγματικές εφαρμογές, τα τμήματα μετατοπίζονται κατά περισσότερο από 1 byte (για το 8086 ήταν 16 byte).
Αυτό που είναι κακό για την τμηματοποίηση είναι ότι είναι περίπλοκο (αλλά νομίζω ότι το γνωρίζετε ήδη;) Αυτό που είναι καλό, είναι ότι μπορείτε να χρησιμοποιήσετε μερικές έξυπνες τεχνικές για να δημιουργήσετε αρθρωτά προγράμματα.
Για παράδειγμα, μπορείτε να φορτώσετε κάποια ενότητα σε ένα τμήμα και, στη συνέχεια, να προσποιηθείτε ότι το τμήμα είναι μικρότερο από ό, τι είναι πραγματικά (αρκετά μικρό για να συγκρατήσει τη λειτουργική μονάδα) και, στη συνέχεια, επιλέξτε το πρώτο τμήμα που δεν αλληλεπικαλύπτεται με αυτό το ψευδο μικρότερο και φορτώστε το επόμενο ενότητα, και ούτω καθεξής. Βασικά, αυτό που παίρνετε με αυτόν τον τρόπο είναι σελίδες μεταβλητού μεγέθους.
Έχετε κάτι να προσθέσετε στην εξήγηση; Ακούστε στα σχόλια. Θέλετε να διαβάσετε περισσότερες απαντήσεις από άλλους χρήστες τεχνολογίας Stack Exchange; Δείτε ολόκληρο το νήμα συζήτησης εδώ .