内存对齐算法

什么是向上对齐?向上对齐是指根据某些硬件平台或函数的要求,对要处理的数据大小需要保证一定的规则。常见的是内存对齐,比如要保证4字节的内存对齐,代码如下(注意其中的符号——&):

 #define MEM_ALIGN_SIZE(size)    (((size) + 3) & (~3))

通常情况下,对齐的大小为2的整数次幂,4,8,16... 这种大小的对齐方式这样写:

 #define ALIGN_SIZE  4
 #define UPPER_ALIGN(size)   (((size) + ALIGN_SIZE - 1) & (~(ALIGN_SIZE - 1)))

比如,某一款存储芯片只能以512字节的方式进行读写,但是为了保证程序的兼容性(有些芯片支持随机读写),读写数据时我不能固定的以512字节进行读写,我会增加一个抽象层,对应用层屏蔽存储芯片的不同。如下图所示:

抽象层中肯定是随机读写函数,但是到了操作具体的存储芯片时就需要保证512字节的对齐了。伪代码如下:

 /*芯片读取函数*/
 #define ALIGN_SIZE  512
 #define UPPER_ALIGN(size)   (((size) + ALIGN_SIZE - 1) & (~(ALIGN_SIZE - 1)))
 int32_t chip_content_read(chip_id, content_buf, read_size)
 {
     //upper align
     read_size = UPPER_ALIGN(read_size);
     ...
 }

注意:

只有要对齐的数字是2的整数次幂的时候,才能使用取地址符号——&。如果数字不是2的整数次幂,那么就该这样写:

 #define ALIGN_SIZE  9
 #define UPPER_ALIGN(size) ((((size) + ALIGN_SIZE - 1) / (ALIGN_SIZE)) * (ALIGN_SIZE))) 

其实,以2的整数次幂进行对齐时,也可以写成上面这种形式,只不过因为对齐的数字是2的整数次幂,有些特殊,故可以使用取地址符&(请大家自行证明下,代码看千遍,不如动手敲一遍)。

Tips

对2的整数次幂的数据进行商和取余,有两个小技巧。假设m为2的整数次幂。

求商——n/m:

n / m = n >> log2(m)

求余——n%m:

n % m = n & (m - 1)

墙裂建议大家看下linux内核中的log2.h,收获多多哟!!!

有时候,不小心知道了一些事,才发现自己所在乎的事是那么可笑。
原文地址:https://www.cnblogs.com/axjlxy/p/15650443.html