Vitis HLS 学习笔记--移除内存分配malloc

时间:2024-06-13 10:48:01

目录

1. 简介

2. 示例解析

2.1 源码解释

2.2 malloc 分析

2.3 替代方案分析

3. 总结


1. 简介

Vitis HLS 也不支持动态创建或删除 C/C++ 对象(用于综合)。

本文探究如何在C/C++代码中避免使用显式的malloc函数来分配内存。在硬件设计和FPGA开发中,避免动态内存分配是一个常见的实践。

通过一个例子,了解 malloc 被用于动态分配内存,但是在 USE_MALLOC 未定义的情况下,代码使用了栈上的局部变量来代替。

2. 示例解析

2.1 源码解释

#include <stdlib.h>

long long example(int din[32], int width) {

#ifdef USE_MALLOC
    long long *out_accum = malloc(sizeof(long long));
    int *array_local = malloc(64 * sizeof(int));
#else
    long long _out_accum;
    long long *out_accum = &_out_accum;
    int _array_local[64];
    int *array_local = &_array_local[0];
#endif
    int i, j;

LOOP_SHIFT:
    for (i = 0; i < 31; i++) {
        if (i < width)
            *(array_local + i) = din[i];
        else
            *(array_local + i) = din[i] >> 2;
    }
    *out_accum = 0;

LOOP_ACCUM:
    for (j = 0; j < 31; j++) {
        *out_accum += *(array_local + j);
    }

  return *out_accum;
}

函数 example 接受一个整数数组 din 和一个选择宽度 width 作为参数。它通过两个循环处理数组:第一个循环 LOOP_SHIFT 根据 width 值对数组元素进行移位操作,第二个循环 LOOP_ACCUM 累加处理后的数组元素到 out_accum。最终,函数返回累加的结果。

2.2 malloc 分析

首先了解 malloc 的用途:

long long *out_accum = malloc(sizeof(long long));

这句代码声明了一个指向long long类型的指针out_accum,并使用malloc函数为它分配了足够存储一个long long类型数据的内存空间。sizeof(long long)是计算long long类型数据大小的操作,确保分配的内存正好可以存放一个long long类型的值。

int *array_local = malloc(64 * sizeof(int));

这句代码声明了一个指向int类型的指针array_local,并使用malloc函数为它分配了足够存储64个int类型数据的内存空间。64 * sizeof(int)是计算64个int类型数据总大小的操作,确保分配的内存可以存放一个包含64个整数的数组。

2.3 替代方案分析

本质上是使用栈内存(stack memory)来替代malloc函数动态分配的堆内存(heap memory)。

  • long long _out_accum; 这行代码在栈上声明了一个long long类型的变量_out_accum。这意味着不需要动态分配内存,因为_out_accum的大小在编译时就已经确定了。
  • long long *out_accum = &_out_accum; 这行代码创建了一个指向_out_accum的指针out_accum。这样,我们就可以像使用动态分配的内存那样使用_out_accum,但实际上它是在栈上分配的,这使得内存的分配和释放更加高效。
  • int _array_local[64]; 这行代码在栈上声明了一个包含64个整数的数组_array_local。与malloc不同,这里不需要在程序运行时分配内存,因为数组的大小在编译时就已经确定了。
  • int *array_local = &_array_local[0]; 这行代码创建了一个指向数组第一个元素的指针array_local。这允许我们通过指针来访问和操作数组,就像它是通过malloc动态分配的一样。

3. 总结

Vitis HLS不支持动态创建或删除C/C++对象,因此开发者必须寻找替代方案。本文通过一个例子展示了如何在不定义USE_MALLOC的情况下,使用栈内存代替堆内存进行内存分配。示例中的函数example通过两个循环处理输入数组,使用栈上的局部变量而非malloc分配的内存,从而在编译时确定内存大小,这对硬件合成至关重要。