#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,收获多多哟!!!