结构体填充与对齐 - 2023.2 简体中文

Vitis 高层次综合用户指南 (UG1399)

Document ID
UG1399
Release Date
2023-12-18
Version
2023.2 简体中文

Vitis HLS 中的结构体根据所使用的 __attributes__#pragmas,可能采用不同类型的填充和对齐方式。这些功能如下所述。

解聚
默认情况下,代码中作为内部变量的结构体已解聚为个别元素。创建的元素数量和类型取决于结构体本身的内容。Vitis HLS 将根据某些最优化条件来判定任一结构体是否将解聚。
提示: 您可使用 AGGREGATE 编译指示或指令来阻止代码中的结构体的默认解聚操作。
图 1. 解聚结构体
聚合
该工具的默认行为是在接口上聚合结构体,如 接口中的结构体 中所述。Vitis HLS 会将结构体的元素连接在一起,从而将此结构体聚合为单一数据单元。此默认操作是根据 AGGREGATE 编译指示或指令完成的,但您无需指定编译指示,因为对于接口上的结构体而言,这是默认行为。聚合过程可能还包含对结构体元素进行位填充,以便按默认 4 字节对齐或指定对齐方式来实现字节结构对齐。
提示: 指定 -Wpadded 作为编译器标志来添加用于填充结构体的多个位时,该工具会发出警告。
已对齐
默认情况下,Vitis HLS 会按 4 字节对齐方式来对齐结构体,通过填充结构体元素来将其对齐到 32 位宽。但您可使用 __attribute__((aligned(X))) 在结构体元素间添加填充,以便将其对齐到“X”字节边界。

重要: 请注意,“X”只能定义为 2 的幂。

__attribute__((aligned)) 不会更改所应用到的变量的大小,而是可以更改结构的存储器布局,方法是在结构体的各元素之间插入填充。由此即可更改结构的大小。

对于含定制数据宽度的结构体中的数据类型(如,ap_int),为其分配的大小为 2 的幂。Vitis HLS 会添加填充位,用于将数据类型的大小对齐到 2 的幂。

Vitis HLS 还将填充 bool 数据类型,以将其对齐到 8 位。

在以下示例中,结构体中 varA 的大小将填充到 8 位(而不是 5 位)。

struct example  {
ap_int<5> varA;
unsigned short int varB;
unsigned short int varC;
int d;
};
图 2. 已对齐的结构体实现
所使用的填充取决于结构体元素的顺序和大小。在以下代码示例中,结构体对齐为 4 字节,Vitis HLS 将在第一个元素 varA 之后添加 2 字节用于填充,在第三个元素 varC 之后再添加 2 字节用于填充。结构体的总计大小将为 96 位。
struct data_t {
  short varA;
  int varB;
  short varC;
};
但如果您按如下方式重写该结构体,则无需填充,而结构体的总计大小将为 64 位。
struct data_t {
  short varA;
  short varC;
  int varB;
};
已封装
Vitis HLS 通过指定 __attribute__(packed(X)) 来封装结构体元素,在此情况下结构体大小取决于结构体每个元素的实际大小。在以下示例中,这意味着结构体大小为 72 位:
图 3. 已封装的结构体实现
提示: 这也可通过使用 AGGREGATE 编译指示或指令的 compact=bit 选项来达成。