How is this size alignment working

人走茶凉 提交于 2020-01-01 05:23:05

问题


I am not able to understand the below code with respect to the comment provided. What does this code does, and what would be the equivalent code for 8-aligned?

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

Here, ssize is of unsigned int type.


回答1:


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

3 in binary is 11, and ~3 is the bitwise negation of those bits, i.e., ...1111100. Performing a bitwise AND with that value will keep every bit the same, except the last two which will be cleared (bit & 1 == bit, and bit & 0 == 0). This gives us a the next lower or equal value that is a multiple of 4.

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




回答2:


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

This gives the size rounded down:

size &= ~(alignment - 1); 

or if you want to round up:

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

The "alignment-1", as long as it's a value that is a power of two, will give you "all ones" up to the bit just under the power of two. ~ inverts all the bits, so you get ones for zeros and zeros for ones.

You can check that something is a power of two by:

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 we use 5 instead:

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

So not a power of two!




回答3:


Perhaps more understandable comment would be

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

Then at least for me, immediate question pops to my mind: should it really be rounded down, when it is size? Wouldn't rounding up be more appropriate:

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

As already said in other answers, to make it 8-aligned, 3 bits need to be zeroed, so use 7 instead of 3. So, we might make 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:


~3 is the bit pattern ...111100. When you do a bitwise AND with that pattern, it clears the bottom two bits, i.e. rounds down to the nearest multiple of 4.

~7 does the same thing for 8-aligned.




回答5:


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

attr->options.ssize &= ~7;



回答6:


number = number & ~3

The number is rounded off to the nearest multiple of 4 that is lesser than number Ex:

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

similarly if number is 4,5,6,or 7,numberis rounded off to 4

But if this is related to memory alignment, the memory must be aligned upwards and not downwards.



来源:https://stackoverflow.com/questions/14561402/how-is-this-size-alignment-working

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!