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. 已封装的结构体实现