嵌入式内存对齐及位运算解析
内存对齐
浅谈内存对齐
位运算
Generating Aligned Memory
栈
gcc
修饰 __attribute__((aligned(32)))
堆
各种内存分配算法保证,为了保证内存对齐,malloc
时需要申请比所要求的内存大的容量,这样可以向下寻找一个保证是对齐大小的整倍数的内存地址
如果 n
为以2为底的m (m > 0, m = 1, 2, 3, …)次幂指数,当以 n
为对齐边界时,称 n – 1
为该对齐边界的对齐掩码(align mask).
#define is_align(A, n) ((A) & ((n) - 1) == 0)
对齐方式:
- 上对齐 align up / round up
- 下对齐 align down / round down
#define align_down(A, n) ((A) & ~((n) - 1)) # 舍弃对齐低位
#define align_up(A, n) (((A) + ((n) - 1)) & !((n) - 1)) # + (n) - 1 跳到下个区间,然后 align down 对齐
计算内存对齐偏移量:
#define align_offset(A, n) (((A) & ((n) - 1) == 0) ? 0 : \
((n) - (A) & ((n) - 1)) & ((n) - 1))
DLMalloc
/* The bit mask value corresponding to MALLOC_ALIGNMENT */
#define CHUNK_ALIGN_MASK (MALLOC_ALIGNMENT - SIZE_T_ONE)
/* True if address a has acceptable alignment */
#define is_aligned(A) (((size_t)((A)) & (CHUNK_ALIGN_MASK)) == 0)
/* the number of bytes to offset an address to align it */
#define align_offset(A)\
((((size_t)(A) & CHUNK_ALIGN_MASK) == 0)? 0 :\
((MALLOC_ALIGNMENT - ((size_t)(A) & CHUNK_ALIGN_MASK)) & CHUNK_ALIGN_MASK))
最后一步 & CHUNK_ALIGN_MASK
是多余的
TLSF
#define BLOCK_ALIGN (sizeof(void *) * 2)
#define MEM_ALIGN ((BLOCK_ALIGN) - 1)
#define ROUNDUP_SIZE(_r) (((_r) + MEM_ALIGN) & ~MEM_ALIGN)
#define ROUNDDOWN_SIZE(_r) ((_r) & ~MEM_ALIGN)
size = (size < MIN_BLOCK_SIZE) ? MIN_BLOCK_SIZE : ROUNDUP_SIZE(size);
malloc内存对齐实现
- 计算申请内存大小:ori_size + 控制块 + alignment
- 申请内存
- align down获取内存对齐首地址
结构体对齐
不存在 #pragma pack
- 第一个成员的首地址为0
- 每个成员的首地址是自身大小的整数倍
- 结构体的总大小,为其成员中所含最大类型的整数倍
struct test
{
char a; //1 + p1
short b; //2
char c; //1 + p1
};
struct test
{
char a; //1 + p3
int b; //4
short c; //2 + p2
};
存在 #pragma pack
按照这个宏声明的和实际数据类型中最大值较小的那个来决定