分配对齐的内存空间
最近用了别人写的一个FFT硬件加速模块,要求DDR中的数据对齐4k边界,估计这个模块用的数据总线是AXI协议的,AXI的突发传输不能超过4k边界。所用的平台是C6678DSP,编译器支持的C++版本是C++98,没有aligned new,所以只能自己写aligned_malloc函数。
额外空间开销
C++的new本质上调用的是malloc函数,malloc可以在堆区申请一定大小的空间,然后返回这段空间的首地址;与之对应的free函数可以释放已分配的堆区空间。
如上图所示,在调用malloc后返回指针,B表示对齐的边界,对齐的字节数是L。一般来说我们得到的指针指向的地址并不是对齐的。但我们可以多分配一点空间,使得数据存放到对齐的位置。那么这样做的话,最糟糕的情况下的额外开销就是L-1,此时指针分配到了“边界+1”的位置处。
从分配的地址如何计算第一个对齐的地址。只需要在分配的地址上加上L-1,再把地址低位清零即可。比如要对齐4k边界:
这样如果已经对齐到边界,那么结果就会是;而如果没有对齐到边界,那么结果就会是当前地址往上的第一个对齐的地址。这个对齐的地址就可以作为aligned_malloc函数的返回值。
空间释放
为了正确释放刚刚分配的空间,我们还需要把,malloc实际分配得到的地址保存下来。是void*类型,所以我们还需要一个sizeof(void*)大小的空间用来存放。这个存放的位置可以就放在对齐的地址的下面。
这个时候最糟糕的情况还是需要额外的L-1字节的空间,malloc分配得到的地址位于“边界-(sizeof(void*)-1)”的位置。
示例代码
1 | void *aligned_malloc(size_t num, size_t alignment){ |
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 小裘控制系统!