内存对齐算法

字节对齐是在分配内存时需要考虑的问题,两个小算法:
假定目前该变量占用n个字节,对齐目标是align,求返回的占用实际内存大小。

(1)最容易想到的算法:

unsigned int calc_align(unsigned int n,unsigned align)
{
    if ( n / align * align == n)
            return n;
 
        return  (n / align + 1) * align;
}

就是判断一下,当前占用的内存字节,是否是alin的整数倍。如果是那么直接返回,这个占用字节数;如果不满足,那么直接加一个align来对齐。

n / align * align == n

只有当n是align的整数倍的时候,可以实现这个等于号。

(2)更好的算法

unsigned int calc_align(unsigned int n,unsigned align)
{
    if ( n / align * align == n)
            return n;
 
        return  (n / align + 1) * align;
}

对于更好的算法原理如下:
2字节对齐,要求地址位为2,4,6,8…,要求二进制位最后一位为0(2的1次方)
4字节对齐,要求地址位为4,8,12,16…,要求二进制位最后两位为0(2的2次方)
8字节对齐,要求地址位为8,16,24,32…,要求二进制位最后三位为0(2的3次方)
16字节对齐,要求地址位为16,32,48,64…,要求二进制位最后四位为0(2的4次方)

由此可见,我们只要对数据补齐对齐所需最少数据,然后将补齐位置0就可以实现对齐计算。

(1)(align-1),表示对齐所需的对齐位,如:2字节对齐为1,4字节为11,8字节为111,16字节为1111…
(2)(x+(align-1)),表示x补齐对齐所需数据
(3)&~(align-1),表示去除由于补齐造成的多余数据
(4) (x+(align-1))&~(align-1),表示对齐后的数据

举个例子:如8字节对齐。目前最小占用6个字节。
6 + (8 - 1)=0000 0110 + 0000 0111 = 0000 1101
0000 1101 & ~(0000 0111) = 0000 1000 //去除由于补齐造成的多余数据

数学证明该公式:

问:

#define _INTSIZEOF(n) ((sizeof(n)+sizeof(int)-1)&~(sizeof(int) - 1) )
说能够在某些系统中内存对齐.(估计是得到一个2 或者4的整数倍)
这个好象就是(x+3)&~3
这样就能满足对齐了吗?
请从数学上给说说.
谢谢

答(作者:win_hate):

对于两个正整数 x, n 总存在整数 q, r 使得

x = nq + r, 其中 0<= r <n //最小非负剩余

q, r 是唯一确定的。q = [x/n], r = x - n[x/n]. 这个是带余除法的一个简单形式。在 c 语言中, q, r 容易计算出来: q = x/n, r = x % n.

所谓把 x 按 n 对齐指的是:若 r=0, 取 qn, 若 r>0, 取 (q+1)n. 这也相当于把 x 表示为:

x = nq + r’, 其中 -n < r’ <=0 //最大非正剩余

nq 是我们所求。关键是如何用 c 语言计算它。由于我们能处理标准的带余除法,所以可以把这个式子转换成一个标准的带余除法,然后加以处理:

x+n = qn + (n+r’),其中 0<n+r’<=n //最大正剩余

x+n-1 = qn + (n+r’-1), 其中 0<= n+r’-1 <n //最小非负剩余

所以 qn = [(x+n-1)/n]n. 用 c 语言计算就是:

((x+n-1)/n)*n

若 n 是 2 的方幂, 比如 2^m,则除为右移 m 位,乘为左移 m 位。所以把 x+n-1 的最低 m 个二进制位清 0就可以了。得到:

(x+n-1) & (~(n-1))

参考博客:
1.内存地址对齐的解析
内存对齐算法
数学证明_2楼正解

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值