ROUND_UP函数详解(STL内存分配的时候 内存对齐上调大小的函数)

时间:2021-02-27 02:22:41

                 

                                        在STL的源码中,或者是其他地方碰到内存对齐的时候 一般会有一个类似于round_up的函数。 一般是像这样子

                  #define __ALIGN   8          //假设是按照8个字节对齐

                  static size_t ROUND_UP(size_t  bytes)

                   {

                          return  (((bytes) + __ALIGN - 1) & ~(__ALIGN  - 1));

                    }

    在我的QQ群有几个人问过 为什么这样子可以实现 上调对齐。

          首先要说的是 这个方法 只适用于 2的N次幂的字节对齐,如果碰到非2的N次幂这个方法是行不通的。

          也就是是说 比如是   ........00000000000001000000000.....类似于这样子的割据。

不能让这个存在两个1.

         首先解释为什么可以实现对齐。先解释& ~(__ALIGN  - 1)。

         比如  .....0000100...假设前面有N个0  后面也有M个0 这, 如果

你减去1,  则  形式必然变为  ....00000111...后面会有M个1,而前面则会有N+1个0.

然后对其取反, 则必然变为   ....11111000.....如果任何数  和它进行与运算,则必然将其小于2的N+1次方的那个值 给去除掉。  比如 你按照8个字节对齐,但是这个数是10,首先让10 + 8 -1, 则变为了17.  则必定把小于8个字节的那一截,也就是17 - 16 =1,这个1 这部分减掉, 而变为16.

      过程就是这样子, 可以实验一下, 比如 是按照8个字节对齐, 则 8的二进制是

...000001000. 那么首先减去1,则必然变为  ...000000111.然后取反,则变为...111111000.如果你拿任何数 和这个数进行与运算, 则000这个部分 必定会被减掉

这个部分 可能是 1,2,3,4,5,6,7。

         如果这个对齐的大小的这个数变为 非2的n次幂的话,则可能是...111..000...11..这种形式,那么最后那个1的高位则不能全部为1 ,如果进行与的时候是什么结果就很难说了。

      如果要使用于 每一种情况的话 可以用这样的一个公式。

       (X + N -1) - [(x + N -1) % N].

这样就跟你对齐的是不是2次幂无关了。 x为你的实际大小,N为对齐的大小。

       道理就是这样子, 希望不懂为什么可以实现的同学能明白。