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

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

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

这里, ssizeunsigned int类型。

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

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

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

所有2的幂(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 

所以不是两个人的力量!

也许更容易理解的评论

 /* 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是位模式...111100 。 当您使用该模式进行按位AND时,它会清除底部的两位,即向下舍入到最接近的4的倍数。

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

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

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

数字四舍五入到最接近的4的倍数,小于number Ex:

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

类似地, if number is 4,5,6,or 7,数字is rounded off to 4

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

    Interesting Posts