How size alignment works

I can not understand the code below regarding the comment provided. What does this code do, and what will be the equivalent code for 8-aligned ?

 /* segment size must be 4-aligned */ attr->options.ssize &= ~3; 

Here ssize is of type unsigned int .

+4
source share
6 answers

Since 4 in binary format is 100, any value aligned with 4-byte boundaries (i.e. a multiple of 4) will have the last two bits set to zero.

3 in binary format is 11, and ~ 3 is the bitwise negation of these bits, that is ... 1111100. Performing bitwise And with this value will keep each bit the same, except for the last two that will be cleared (bit and 1 == bit , bit and 0 == 0). This gives us the next lower or equal value, which is a multiple of 4.

To perform the same operation for 8 (1000 in binary), we need to clear the least significant three bits. We can do this with the bitwise negation of binary 111, i.e. ~ 7.

+8
source

All powers of two (1, 2, 4, 8, 16, 32 ...) can be aligned using simple operations a and.

In this case, the size is rounded:

 size &= ~(alignment - 1); 

or if you want to round:

 size = (size + alignment-1) & ~(alignment-1); 

"alignment-1", if this value is two, it will give you "all" up to a bit just below two. ~ inverts all bits, so you get them for zeros and zeros for them.

You can verify that something has the power of two:

 bool power_of_two = !(alignment & (alignment-1)) 

This works because, for example, 4:

 4 = 00000100 4-1 = 00000011 & -------- 0 = 00000000 

or for 16:

 16 = 00010000 16-1 = 00001111 & -------- 0 = 00000000 

If instead use 5:

 5 = 00000101 4-1 = 00000100 & -------- 4 = 00000100 

So not the power of two!

+4
source

Perhaps a more understandable comment would be

 /* make segment size 4-aligned by zeroing two least significant bits, effectively rounding down */ 

Then, at least for me, the question immediately arises: will it really be rounded when it is the size? Rounding would not be more appropriate:

 attr->options.ssize = (attr->options.ssize + 3) & ~3; 

As already mentioned in other answers, to make it 8-aligned, you need to clear 3 bits, so use 7 instead of 3 . Thus, we can turn it into a function:

 unsigned size_align(unsigned size, unsigned bit_count_to_zero) { unsigned bits = (1 << bit_count_to_zero) - 1; return (size + bits) & ~bits; } 
+4
source

~3 is a bit pattern ...111100 . When you execute bitwise AND with this pattern, it clears the bottom two bits, i.e. Rounds to the nearest multiple of 4.

~7 does the same for 8-aligned ones.

+2
source

The code ensures that the bottom two ssize bits are cleared, ensuring that ssize is a multiple of 4. Equivalent code for 8-aligned ones will be

 attr->options.ssize &= ~7; 
+1
source
 number = number & ~3 

the number is rounded to the nearest multiple of 4, which is less than number Example:

  if number is 0,1,2 or 3, the `number` is rounded off to 0 

same as if number is 4,5,6,or 7, number is rounded off to 4

But if it involves memory alignment , the memory should be aligned up, not down.

0
source

All Articles