« Les opérations bit à bit/Les débordements de puissance de deux » : différence entre les versions
Contenu supprimé Contenu ajouté
mAucun résumé des modifications |
|||
Ligne 1 :
Comme vous le savez peut-être, certaines architectures demandent aux accès mémoire de respecter des contraintes d'alignement. Pour rappel, la mémoire est alors découpée en blocs dont la taille est égale à la largeur du bus de données. Quand on accède à une donnée, il est préférable que celle-ci soit intégralement contenue dans un bloc : l'accès mémoire est alors dit aligné. Mais si la donnée est à cheval sur deux blocs, l'accès mémoire est dit non-aligné et cela peut poser problème. Si certaines architectures gèrent parfaitement les accès non-alignés, d'autres ne permettent pas de tels accès. Pour diverses raisons, il est possible pour un programmeur de détecter si un accès mémoire sera ou non aligné.
Ligne 11 ⟶ 5 :
Gérer les accès non-alignés demande donc de détecter quand une donnée est à cheval entre deux blocs. Détecter les accès non-alignés est primordial et, fort heureusement, se fait avec quelques calculs particulièrement simples. Pour cela, il existe plusieurs solutions différentes.
L'adresse <math>A</math> peut se calculer à partir d'autres paramètres, comme la taille des blocs. Déjà, il faut savoir que chaque bloc a une taille qui s'exprime en ''bytes''. Avec un système d'alignement ou de page, chaque bloc est numéroté en partant de zéro, ce numéro étant l'équivalent de l'adresse pour les ''bytes''. L'adresse d'un bloc est par convention l'adresse du premier ''byte'' du bloc, celui dont l'adresse est la plus basse. Elle se calcule donc en multipliant le numéro du bloc par sa taille. Une donnée à l'intérieur d'un bloc est généralement localisée à une certaine distance de l'adresse de base, elle est placée quelques ''bytes'' plus loin que la base du bloc. Dit autrement, l'adresse <math>A</math> d'une donnée s'écrit comme suit :
Ligne 27 ⟶ 21 :
Notons que faire la division en question demande juste de faire un décalage vers la droite, du moins sous condition que la taille du bloc soit une puissance de deux. C'est d'ailleurs une des raisons pour lesquelles les blocs/pages ont une taille égale à une puissance de deux. Faire ainsi simplifie de nombreux calculs d'adresse et permet des simplifications assez utiles.
Il existe une seconde méthode qui une logique très simple. La donnée à charger commence à une adresse que nous noterons <math>A</math> et a une longueur <math>L</math>. Un débordement de page/bloc a lieu quand il existe un multiple de <math>2^n</math> entre <math>A</math> et <math>A + L</math>. Cela traduit le fait que la donnée commence dans un premier bloc, atteint la limite du bloc (donc, une adresse multiple de <math>2^n</math>) et se poursuit au-delà. Reste à voir comment les opérations bit à bit nous aident pour détecter une telle situation.
Ligne 65 ⟶ 59 :
: <math>(A \mod 2^n) + L \geq 2^n</math>
Une seconde méthode effectue un calcul similaire, si ce n'est que la comparaison est remplacée par un débordement d'entier. Le principe est très simple et se contente de remplacer l'adresse par le multiple de <math>2^n</math> le plus grand possible qui soit adressable. Prenons par exemple une mémoire de 2^32 adresses, adressée par des adresses de 32 bits, découpée en page de 4096 octets. On suppose aussi que la machine travaille sur les mots/registres de 32 bits, comme les adresses. Sur 32 bits, l'adresse la plus grande qui soit multiple de 4096 est de 4294963200. Si à cette adresse on ajoute <math>L + A \mod 2^n</math>, un débordement se produit si <math>L + A \% 2^n > 4096</math>. En clair, le débordement d'entier traduit un débordement de page. On détecte donc un débordement de page si :
Ligne 82 ⟶ 76 :
: <math>(A | - m) + L > 2^{n}</math>
{{NavChapitre | book=Les opérations bit à bit
|