Je ne suis pas en mesure de comprendre le code ci-dessous en ce qui concerne le commentaire fourni. Qu’est-ce que ce code fait, et quel serait le code équivalent pour 8-aligned
?
/* segment size must be 4-aligned */ attr->options.ssize &= ~3;
Ici, ssize
est de type unsigned int
.
Puisque 4 en binary est égal à 100, toute valeur alignée sur des limites de 4 octets (soit un multiple de 4) aura les deux derniers bits mis à zéro.
3 en binary est 11, et ~ 3 est la négation au niveau du bit de ces bits, c’est-à-dire, … 1111100. Effectuer un bit AND avec cette valeur gardera tous les bits identiques, sauf les deux derniers qui seront effacés (bit & 1 == bit et bit & 0 == 0). Cela nous donne une valeur inférieure ou égale à un multiple de 4.
Pour effectuer la même opération pour 8 (1000 en binary), nous devons effacer les trois bits les plus bas. Nous pouvons le faire avec la négation au niveau du bit du binary 111, c’est-à-dire ~ 7.
Toutes les puissances de deux (1, 2, 4, 8, 16, 32 …) peuvent être alignées par une simple opération et.
Cela donne la taille arrondie:
size &= ~(alignment - 1);
ou si vous voulez arrondir:
size = (size + alignment-1) & ~(alignment-1);
L ‘”alignement-1″, tant que la valeur est une puissance de deux, vous donnera “tous les 1” jusqu’au bit juste sous la puissance de deux. ~
Inverse tous les bits, vous obtenez donc ceux pour les zéros et les zéros pour les uns.
Vous pouvez vérifier que quelque chose est une puissance de deux en:
bool power_of_two = !(alignment & (alignment-1))
Cela fonctionne parce que, par exemple 4:
4 = 00000100 4-1 = 00000011 & -------- 0 = 00000000
ou pour 16 ans:
16 = 00010000 16-1 = 00001111 & -------- 0 = 00000000
Si on utilise 5 à la place:
5 = 00000101 4-1 = 00000100 & -------- 4 = 00000100
Donc pas une puissance de deux!
Peut-être un commentaire plus compréhensible serait
/* make segment size 4-aligned by zeroing two least significant bits, effectively rounding down */
Alors au moins pour moi, une question immédiate me vient à l’esprit: faut-il vraiment arrondir à la taille, quand il est? Arrondir ne serait-il pas plus approprié:
attr->options.ssize = (attr->options.ssize + 3) & ~3;
Comme cela a déjà été dit dans d’autres réponses, pour qu’il soit aligné sur 8, 3 bits doivent être mis à zéro, utilisez donc 7
au lieu de 3
. Donc, nous pourrions en faire une fonction:
unsigned size_align(unsigned size, unsigned bit_count_to_zero) { unsigned bits = (1 << bit_count_to_zero) - 1; return (size + bits) & ~bits; }
~3
est le motif de bits ...111100
. Lorsque vous faites un bit AND avec ce motif, les deux bits inférieurs sont effacés, c’est-à-dire qu’ils arrondissent au multiple de 4 le plus proche.
~7
fait la même chose pour 8 alignés.
Le code assure la ssize
deux derniers bits de la ssize
, garantissant que ssize
est un multiple de 4. Un code équivalent pour 8 alignés serait
attr->options.ssize &= ~7;
number = number & ~3
Le nombre est arrondi au multiple de 4 le plus proche qui est inférieur au number
Ex:
if number is 0,1,2 or 3, the `number` is rounded off to 0
de même if number is 4,5,6,or 7,
nombre is rounded off to 4
Mais si cela est lié à l’ alignement de la mémoire, celle-ci doit être alignée vers le haut et non vers le bas.