分配对齐的堆区空间

  最近用了别人写的一个FFT硬件加速模块,要求DDR中的数据对齐4k边界,估计这个模块用的数据总线是AXI协议的,AXI的突发传输不能超过4k边界。所用的平台是C6678DSP,编译器支持的C++版本是C++98,没有aligned new,所以只能自己写aligned_malloc函数。


  • 20220915更新

  才知道有一个stdlib.h里有一个memalign,可以用来在堆区开辟对齐的堆区空间,对齐的地址只能是2的整数次幂。不过用起来也很方便,那样就不用自己写aligned_malloc和aligned_free了。由memalign分配的空间可以用free来释放。


额外空间开销

在这里插入图片描述
  C++的new本质上调用的是malloc函数,malloc可以在堆区申请一定大小的空间,然后返回这段空间的首地址;与之对应的free函数可以释放已分配的堆区空间。
  如上图所示,在调用malloc后返回指针 p p p,B表示对齐的边界,对齐的字节数是L。一般来说我们得到的 p p p指针指向的地址并不是对齐的。但我们可以多分配一点空间,使得数据存放到对齐的位置。那么这样做的话,最糟糕的情况下的额外开销就是L-1,此时 p p p指针分配到了“边界+1”的位置处。
  从分配的地址如何计算第一个对齐的地址。只需要在分配的地址上加上L-1,再把地址低位清零即可。比如要对齐4k边界:
a d d r a l i g n e d = ( p + 0 x F F F ) & ∼ ( 0 x F F F ) {{addr_{aligned} = (p + \rm{0xFFF})\& \sim(\rm{0xFFF})}} addraligned=(p+0xFFF)&(0xFFF)
  这样如果 p p p已经对齐到边界,那么结果就会是 p p p;而 p p p如果没有对齐到边界,那么结果就会是当前地址往上的第一个对齐的地址。这个对齐的地址就可以作为aligned_malloc函数的返回值。

空间释放

  
  为了正确释放刚刚分配的空间,我们还需要把,malloc实际分配得到的地址 p p p保存下来。 p p p是void*类型,所以我们还需要一个sizeof(void*)大小的空间用来存放 p p p。这个存放的位置可以就放在对齐的地址的下面。
在这里插入图片描述
  这个时候最糟糕的情况还是需要额外的L-1字节的空间,malloc分配得到的地址位于“边界-(sizeof(void*)-1)”的位置。

示例代码

void *aligned_malloc(size_t num, size_t alignment){
	void *pOrig, *pAligned;
	size_t offset;

	// check alignment is power of 2
	if((alignment & (alignment - 1)) != 0) pAligned = NULL;
	else{
		offset = alignment - 1 + sizeof(void *);
		pOrig = malloc(num + offset);
		pAligned = (void *)(((size_t)pOrig + (size_t)offset) & (~(alignment-1)));
		*((void **)((size_t)pAligned-sizeof(void *))) = pOrig;
	}

	return pAligned;
}

void aligned_free(void *pAligned){
	void **p = (void **)((size_t)pAligned- sizeof(void *));
	free(*p);
}
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小裘HUST

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值