2

define一句话是 :

#define _INTSIZEOF(n)   ( (sizeof(n) + sizeof(int) - 1) & ~(sizeof(int) - 1) )

我被告知目的是位对齐。
我想知道它是如何工作的,提前谢谢。

4

3 回答 3

9

上面的宏只是将 的大小n与最近的大于或等于sizeof(int)边界对齐。

a将值与最近的大于或等于任意边界对齐的基本算法b

  1. 除以四舍五入然后a_b
  2. 再次乘以商b

在无符号(或只是正)值的域中,第一步是通过以下流行的技巧实现的

q = (a + b - 1) / b
// where `/` is ordinary C-style integer division (rounding down)
// Now `q` is `a` divided by `b` rounded up

将此与第二步结合起来,我们得到以下结果

aligned_a = (a + b - 1) / b * b

aligned_a您获得所需的对齐值。

将此算法应用于手头的问题将得到以下_INTSIZEOF宏的实现

#define _INTSIZEOF(n)\
  ( (sizeof(n) + sizeof(int) - 1) / sizeof(int) * sizeof(int) )

这已经足够好了。

但是,如果您事先知道对齐边界是 2 的幂,则可以通过用简单的按位运算替换除法+乘法序列来“优化”计算

aligned_a = (a + b - 1) & ~(b - 1)

这正是上述_INTSIZEOF宏的原始实现中所做的。

这种“优化”可能对某些编译器有意义(尽管我希望现代编译器能够自行解决)。但是,考虑到上述_INTSIZEOF(n)宏显然是用作编译时表达式(它不依赖于任何运行时值,除了作为 传递的 VLA 对象/类型n),以这种方式优化它没有多大意义。

于 2013-01-05T20:03:48.543 回答
3

这里有一个提示:

一个常用的方法ceil(a/b)是:

(a + (b-1)) / b
于 2013-01-05T19:56:01.223 回答
0

b * ( (a + b - 1) / b ) = (a + b - 1) & ~(b - 1)

要了解上述原因为何成立,请考虑以下几点:

第一部分(为什么 q = (a + b - 1) / b 产生我们正在寻找的数字):

...请注意,我们希望 q 是 a 中 b 的数量,但向上取整(即,如果整数除法后有余数,则该余数应向上取整为 b,因此 q 增加 1 )。

存在 Q 和 R 使得 a = Qb + R,因此 a + b - 1 = Qb + b - 1 + R。如果我们对 a + b - 1 进行整数除法,我们将得到 Q + (b- 1+R)/b。如果 R 为零,则第二部分将为零,如果 R 不为零,则为 1(注意 R 保证小于 b)。

第二部分(宏):

现在如果 b 是 2 的幂,那么 a + b - 1 除以 b 只是 b 的指数的右移(即 b = 2^n,然后右移 n 位)。

此外,乘以 b 是左移(左移 n 位)

因此结合起来,我们所做的就是将最右边的 n 位清除为零,这是通过屏蔽来实现的:~(b-1) 给我们 1111...111000...0 其中 1 的数量等于 n ( b = 2^n)

于 2018-10-01T17:50:05.610 回答