0%

嵌入式内对齐及相关位运算

嵌入式内存对齐及位运算解析

内存对齐

浅谈内存对齐
位运算
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

  1. 第一个成员的首地址为0
  2. 每个成员的首地址是自身大小的整数倍
  3. 结构体的总大小,为其成员中所含最大类型的整数倍
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

按照这个宏声明的和实际数据类型中最大值较小的那个来决定