C编程技巧——向上或向下对齐的方法及原理

C编程技巧——向上或向下对齐的方法及原理在编程中经常使用字节对齐来管理分配的内存 需要字节对齐的根本原因在于 CPU 访问数据的效率和存储空间的使用率问题 例如 一个处理器一次总是从存储器中取出 4 个字节的数据

大家好,欢迎来到IT知识分享网。

在编程中经常使用字节对齐来管理分配的内存,需要字节对齐的根本原因在于CPU访问数据的效率和存储空间的使用率问题。例如,一个处理器一次总是从存储器中取出4个字节的数据。如果所有的int类型(这里默认int类型占4个字节)数据的地址对齐成4的倍数,那么就可以用一个操作来读或写int型的数据了。否则,我们可能需要执行多次操作来实现一个int型数据的访问,因为数据可能被分放在几个4字节的存储块中,这样效率会明显降低很多。

总体而言,字节对齐满足如下简单规律(其余的以此类推):

2字节对齐:要求地址为2, 4, 6, 8…,二进制地址的最后一位为0(2的1次方)

4字节对齐:要求地址为4,8,12,16…,二进制地址的最后两位为0(2的2次方)

上述是字节对齐的简单描述,相信有过C编程经验的同学肯定是一看就明白了。有时候在编程时,要动态分配内存了,为了能充分利用内存空间和数据安全,总是会要求把分配的内存按一定的要求向上或向下对齐,那么这时候该怎么操作呢?

首先看两个宏定义(取自RT-Thread源码)

向上对齐:

#define RT_ALIGN(size, align) (((size) + (align) - 1) & ~((align) - 1))

向下对齐:

#define RT_ALIGN_DOWN(size, align) ((size) & ~((align) - 1))

向上或向下对齐,换个通俗的描述就是

向上对齐:计算size以align为倍数的上界数(15以8为倍数的上界数:16)

向下对齐:计算size以align为倍数的下界数(15以8为倍数的下界数:8)

以上描述,相信大家一看就明白了,那么怎么通过编码实现呢?还是以一个实例来看

向下对齐

例:计算size以align字节向下对齐(int类型,这里定义占4个字节)

int size = 15; int align = 8;

以二进制理解其原理,其实开篇就给出了答案:

8字节对齐:要求地址为8,16,24,32…,二进制地址的最后三位为0,即:align = 8;

size对齐后二进制后三位为:000

xxxxxxxx xxxxxxxx xxxxxxxx xxxxx000

size要得到以上数,是不是与运算下面这个数呢

   

上面二进制数就是~((align) – 1),该数可以称其为对齐字节的掩码

那么size的运算如下:

size二进制表示:

00000000 00000000 00000000 00001111

按8字节对齐后为

00000000 00000000 00000000 00001000

即:size为8

那么整个运算过程就是下面这个式子,这样就得到了向下对齐的数

((size) & ~((align) - 1))

向上对齐

同理,要向上对齐,用的对齐字节的掩码还是一样:~((align) – 1),只需把size向上扩展一个(align-1)即可,即加上(align-1)

(((size) + (align) - 1) & ~((align) - 1))

这里可以理解下,加align-1是为了向上补齐,找出上界,看是否满align个字节

这里有的同学可能要问了,怎么不是加align,而是align-1呢?

还是举个例子:align = 8

如size=16,8字节对齐的上界数就是16,此时加上align-1是23,运算后还是16,解释如下:

16原本就是8的倍数,余数为0,向上扩展align-1个字节后,不满一个align大小,所以对齐后还是16,如果是向上扩展align,就直接加了一个align大小,显然不对

如size=18,8字节对齐的上界数为24,此时加上align-1是25,运算后还是24,解释如下:

18不是8的倍数,8字节对齐后,还余2个字节,要求是向上对齐,那么就需要把这2个字节凑个8字节,这时候加align-1,就变成9个字节,满足一个align大小,所以运算的结果就是24

不是加align,而是align-1,显然明白了吧,就是一个数学问题,与求商和余数是一个道理。

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://yundeesoft.com/95449.html

(0)

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注微信