7

关于提供的评论,我无法理解以下代码。这段代码有什么作用,等价的代码是8-aligned什么?

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

这里,ssizeunsigned int类型。

4

6 回答 6

13

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

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

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

于 2013-01-28T11:56:16.827 回答
12

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

所以不是二的幂!

于 2013-01-28T12:12:54.057 回答
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;
}
于 2013-01-28T12:16:43.523 回答
2

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

~7对 8-aligned 做同样的事情。

于 2013-01-28T11:51:43.727 回答
1

该代码确保清除 的底部两位ssize,确保它ssize是 4 的倍数。8 对齐的等效代码为

attr->options.ssize &= ~7;
于 2013-01-28T11:52:00.387 回答
0
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

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

于 2013-01-28T12:13:05.413 回答