MySQL中的ALIGN_SIZE宏解释

   在看MySQL的内存池分配的时候,看见了ALIGN_SIZE宏,知道是用作字节对齐的,实现原理如何不甚很明白,在网上查了一下。找到了这么一篇http://bbs.chinaunix.net/archiver/tid-846225.html解释,该页面布局不太好看,就搬到这里来了。很实用的。

原帖内容:

以前对于这个宏有讨论过,不过似乎都讲得很模糊,作为一个知识点不应该有模糊
这个宏的目的是:将地址值调整为下一个边界上。
先问问自己:我应该怎么去实现这个功能呢?
假设: addr = 0xbfdf8cf3        也就是:1011 1111 1101 1111 1000 1100 1111 0011
那么:如果我要将这个值调整到下一个2字节边界上
      
就应该是:xxxx xxxx xxxx xxxx xxxx xxxx xxxx xx10
         
也就是2的倍数上。
      
如果我要将这个值调整到下一个4字节边界上
      
就应该是:xxxx xxxx xxxx xxxx xxxx xxxx xxxx x100 
      
也就是4的倍数上。
      
最后,如果我要将这个值调整到下一个8字节界边上
      
就应该是:xxxx xxxx xxxx xxxx xxxx xxxx xxxx 1000
         
也就是8的倍数上
怎么做呢? 我必须根据所要调整边界的要求 将 addr 的低几位置 0,同时还要增加一个 模值
例如:我要将 addr 调整到 4 字节界上,于是我就有一个初步的想法
1
addr 加上 0100 使它跳到下一个 4 字节
    addr + 0000 0000 0000 0000 0000 0000 0000 0100
      
结果为:1011 1111 1101 1111 1000 1100 1111 0111
2
、将上一步的结果低 2 位清 0,从而实现调整要求
   1011 1111 1101 1111 1000 1100 1111 0111 
&  1111 1111 1111 1111 1111 1111 1111 1100
--------------------------------------------------------------
    1011 1111 1101 1111 1000 1100 1111 0100
3
1111 1111 1111 1111 1111 1111 1111 1100 怎么通过 4 运算得出来呢?
   
负数:-4 在机器中表示为: -4 = ~4 + 1
              
即: 1111 1111 1111 1111 1111 1111 1111 1011        =  ~4
                  + 0000 0000 0000 0000 0000 0000 0000 0001        =  1
                 -----------------------------------------------------------------------------
                     1111 1111 1111 1111 1111 1111 1111 1100        =  -4
   
4
、总结一下,得出以下算法
    (addr + align_size) & (-align_size)
所以:我可以这样定义这个宏
#define PAGE_ALIGN(addr, align_size)  ((addr+align_size) & (-align_size))
而后来:我发现,只要加上被清0位数上的最大值,就可以跳到下一个对齐边界上,
        
也就是: 4 字节对齐时,只要加上3就可以了,
                 8
字节对齐时,只要加上7就可以了,
                 2
字节对齐时,只要加上1就可以了,

            
即: addr + align_size - 1 就可以了 !!!
        
下一步做 & 时:4字节对齐,只要将 3 取反就得出 0xFFFF FFF4
                                   8
字节对齐,只要将 7 取反就得出 0xFFFF FFF8
                                   2
字节对齐,只要将 1 取反就得出 0xFFFF FFF2
    
于是: 我就有了算法的另一个版本:
       ( addr + align_size - 1 ) & (~(align_size - 1))       
最后, 我就可以将宏定义为:       
#define PAGE_ALIGN(addr, align_size) ((addr+align_size-1) & ~(align_size-1))
也就是,LZ 所问的宏是怎么来的

补充一点:

(addr + align_size) & (-align_size)

这个算法,忽略了对 低几位是 0 的情况的考虑!

如果:xxxx xxxx xxxx xxxx xxxx xxxx xxxx xx00 
这种情况的话 addr + align_size 导致空跳到下一边界
addr + align_size - 1 无论什么情况下都是正确的。

-align_size 与 ~ (align_size - 1) 本质上是一样的, 而 - align_size 似乎更好理解,建议采用这种形式 

 

讲得很细,真是学习了,在此谢谢作者的讲解,也谢谢MySQL团队,谢谢开源,谢谢每一个乐观向上的人

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值