在 C 代码中,如果有多个比较小的数组,可以通过映射(map)将其合并成一个大的数组,大的数组会消耗相应的 RAM,这样做可以减少消耗的 RAM 的数量。
(思考:是否会减少消耗的存储空间?比如通过减少 RAM 数量来减少空间冗余?)
Q:多小是小
Vivado HLS 提供了两种 ARRAY_MAP 的方式,一种是横向映射(Horizontal mapping)一种是纵向映射(Vertical mapping)。
映射(合并)
Horizontal mapping
横向 Map 就是将多个数组的元素拼接在一起,新的数组元素个数是之前各个小数组元素个数的和,元素的位宽保持不变。
对于横向映射是可以允许有 offset 的,这里的 offset 是指地址的偏移。从下图可以看出两个数组并不是无缝对接的, 而是有两个地址的空挡。(思考:为什么要有 offset?)
横向映射虽然能减少相应 memory 的资源消耗,但是对数据的吞吐率并没有改善,因为memory 个数减少了意味着读取数据的端口的个数也减少了
2 Vertical mapping
纵向映射就是把对应位置的元素做位拼接,最终的数组元素个数等于之前各个小数组中最长的数组的元素个数,但是位宽会发生变化,因为做了位拼接。新数组位宽是对应位置各个数组元素位宽之和。ARRAY_MAP 指令设置界面的参数 instance 的作用是指定合并之后的新数组的名称。
还可以将数组分块和数组映射结合起来,先将数组分块,然后再将分块的数组通过横向映射合并起来,如图 21-4 所示,这样做的好处是“既可以在减少资源的同时也可以获得一定的数据吞吐率”
针对不同数组
先对两个数组分别按行切开,再按行拼接
(思考:为什么要这样先分割再横向合并呢?优化的原理是什么?)
重组
减少BRAM
ARRAY_RESHAPE 相当于是将 ARRAY_PARTITION 和纵向的 ARRAY_MAP 结合在一起的,这样能降低资源消耗,同时也有利于数据的并行访问。类似于 ARRAY_PARTITION 的三种方式,ARRAY_RESHAPE 也有 block、cyclic 和 complete 三种方式。
是针对同一个数组。
eg
用A B缓存pa pb
数据处理A , B
A, B返回pa pb
Q??:此处资源利用并没有减少啊??
总结
ARRAY_MAP 可以减少 RAM 资源消耗,但是并不能改善吞吐率。而 ARRAY_RESHAPE 可以通过本身包含的 ARRAY_PARTITION 来改善吞吐率,同时在一定程度上获得了资源和吞吐率的折中。