这个尺寸对齐是如何工作的
关于提供的评论,我无法理解以下代码。 这段代码做了什么,以及8-aligned
的等效代码是什么?
/* segment size must be 4-aligned */ attr->options.ssize &= ~3;
这里, ssize
是unsigned 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
但如果这与内存对齐有关 ,则内存必须向上而不是向下对齐。