关于提供的评论,我无法理解以下代码。这段代码有什么作用,等价的代码是8-aligned
什么?
/* segment size must be 4-aligned */
attr->options.ssize &= ~3;
这里,ssize
是unsigned int
类型。
关于提供的评论,我无法理解以下代码。这段代码有什么作用,等价的代码是8-aligned
什么?
/* segment size must be 4-aligned */
attr->options.ssize &= ~3;
这里,ssize
是unsigned int
类型。
由于二进制中的 4 是 100,任何与 4 字节边界对齐的值(即 4 的倍数)都将最后两位设置为零。
二进制中的 3 是 11,~3 是这些位的按位否定,即 ...1111100。使用该值执行按位与将保持每个位相同,除了最后两个将被清除(位 & 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 的幂以下。~
反转所有位,所以你得到一个零和零。
您可以通过以下方式检查某物是否为 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
。当您使用该模式进行按位与时,它会清除底部的两位,即向下舍入到最接近的 4 倍数。
~7
对 8-aligned 做同样的事情。
该代码确保清除 的底部两位ssize
,确保它ssize
是 4 的倍数。8 对齐的等效代码为
attr->options.ssize &= ~7;
number = number & ~3
该数字四舍五入到小于 Ex 的最接近的
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,
号码is rounded off to 4
但是如果这与内存对齐有关,则内存必须向上对齐而不是向下对齐。