这个尺寸对齐是如何工作的

时间:2013-01-28 11:50:37

标签: c++ c struct bit-manipulation memory-alignment

我无法理解以下有关所提供评论的代码。这段代码做了什么,以及8-aligned的等效代码是什么?

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

此处,ssize属于unsigned int类型。

6 个答案:

答案 0 :(得分:11)

由于二进制4是100,任何与4字节边界对齐的值(即4的倍数)都会将最后两位设置为零。

二进制中的3是11,并且~3是这些位的按位否定,即...... 1111100。执行与该值的按位AND将使每个位保持相同,除了将被清除的最后两个(位& 1 ==位,以及位& 0 == 0)。这给了我们一个下一个或更小的值,它是4的倍数。

要对8(二进制1000)执行相同的操作,我们需要清除最低的三位。我们可以通过二进制111的按位否定来做到这一点,即~7。

答案 1 :(得分:8)

两个(1,2,4,8,16,32 ......)的所有幂可以通过简单的a和操作对齐。

这样可以缩小尺寸:

size &= ~(alignment - 1); 

或者如果你想要整理:

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

“alignment-1”,只要它是一个2的幂的值,就会给你“所有的”直到2的幂。 ~将所有位反转,因此您可以获得零和0的零。

你可以通过以下方式检查某事情是否为2:

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

这是有效的,例如4:

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

或16:

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

如果我们使用5代替:

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

所以不是两个人的力量!

答案 2 :(得分:5)

也许更容易理解的评论

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

然后至少对我来说,我立即想到了一个问题:它是否真的应该向下舍入,当它的大小?不会四舍五入更合适:

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

正如在其他答案中已经说过的那样,要使其为8对齐,需要将3位置零,因此请使用7代替3。所以,我们可能会把它变成一个函数:

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

答案 3 :(得分:2)

~3是位模式...111100。当你使用该模式进行按位AND时,它会清除底部的两位,即向下舍入到最接近的4的倍数。

~7对8对齐做了同样的事情。

答案 4 :(得分:1)

代码确保清除ssize的后两位,保证ssize是4的倍数.8对齐的等效代码将是

attr->options.ssize &= ~7;

答案 5 :(得分:0)

number = number & ~3

数字四舍五入到 <4> 例如:

number

类似 if number is 0,1,2 or 3, the `number` is rounded off to 0 if number is 4,5,6,or 7,

但如果这与内存对齐有关,则内存必须向上而不是向下对齐。