Vitis HLS 学习笔记--优化指令-ARRAY_PARTITION

ops/2025/3/5 3:16:57/

目录

1. ARRAY_PARTITION 概述

2. 语法解析

2.1 参数解释

2.1.1 variable

2.1.2 type

2.1.3 factor

2.1.4 dim

2.2 典型示例

2.2.1 dim=1

2.2.2 dim=2

2.2.3 dim=0

3. 实例演示

4. 总结


1. ARRAY_PARTITION 概述

ARRAY_PARTITION 指令中非常重要,它用于优化数组的存储和访问。该指令可以将一个大数组分割成多个小数组,以提高并行处理能力和减少访问延迟。

其实这个过程类比到RTL种,就是手动分配如下数组:

reg [数据位宽-1:0] my_array [维度2:0][维度1:0];

HLS 提供了一个更高级的抽象层次,允许我们在不需要关心将 my_array 分解为多少个子数组以优化访问时序的情况下进行操作。它为数组分割的快速分析和实施提供了一种极为便捷的方法。

2. 语法解析

#pragma HLS array_partition variable=<name> type=<type> factor=<int> dim=<int>

2.1 参数解释

2.1.1 variable

必要实参,用于指定要分区的阵列变量。

2.1.2 type

指定分区类型,可选。默认类型为 complete。支持以下类型:

  • cyclic:循环分区会通过交织来自原始阵列的元素来创建更小的阵列。该阵列按循环进行分区,具体方式是在每个新阵列中放入一个元素,然后回到第一个阵列以重复该循环直至阵列完全完成分区为止。例如,如果使用 factor=3:
    • 向第 1 个新阵列分配元素 0
    • 向第 2 个新阵列分配元素 1
    • 向第 3 个新阵列分配元素 2
    • 向第 4 个新阵列分配元素 3
  • block:块分区会从原始阵列的连续块创建更小阵列。这样可将阵列有效分区为 N 个相等的块,其中 N 为 factor= 实参定义的整数。
  • complete:完全分区可将阵列分解为多个独立元素。对于一维阵列,这对应于将存储器解析为独立寄存器。这是默认 <type>。

2.1.3 factor

指定要创建的更小的阵列数量。

仅对于 block 和 cyclic 型分区生效!

2.1.4 dim

指定要分区的多维阵列的维度。针对含 <N> 维的阵列,指定范围介于 0 到 <N> 之间的整数:

  • 如果使用 0 值,则使用指定的类型和因子选项对多维阵列的所有维度进行分区。
  • 任意非零值均表示只对指定维度进行分区。例如,如果使用的值为 1,则仅对第 1 个维度进行分区。

2.2 典型示例

complete类型比较多见,故选择此类型进行分析。

int l_A[2][5];
#pragma HLS ARRAY_PARTITION variable=l_A type=complete dim=?

对于l_A[2][5],其元素分布如下:

l_A[0][0]

l_A[0][1]

l_A[0][2]

l_A[0][3]

l_A[0][4]

l_A[1][0]

l_A[1][1]

l_A[1][2]

l_A[1][3]

l_A[1][4]

2.2.1 dim=1

第 1 个维度进行分区,相当于将l_A[2][5]拆分成两个2元素数组。

它们分别存储在2个 ram_1p 的存储器中。

可以同时访问所有l_A[0][x]和l_A[1][x]。

该分区方法,每个时钟周期可以读取两个数据。

2.2.2 dim=2

第 1 个维度进行分区,相当于将l_A[2][5]拆分成两个5元素数组。

它们分别存储在5个 ram_1p 的存储器种。

可以同时访问所有l_A[x][0]、l_A[x][1]、l_A[x][2]、l_A[x][3]、l_A[x][4]。

该分区方法,每个时钟周期可以读取5个数据。

2.2.3 dim=0

当dim=0时,表示对整个数组进行完全分区,不考虑具体的维度。这意味着数组的每个元素都将被单独存储,完全独立地占用资源。对于l_A[2][5],这将导致所有10个元素都被独立存储,每个元素可以被单独访问,这最大化了并行访问能力,但也大量占用资源。

3. 实例演示

#include <stdio.h>
#include <string.h>#define MAX_SIZE 16const unsigned int c_dim = MAX_SIZE;extern "C" {
void matmul(int* in1, int* in2, int* out_r, int size, int rep_count) {// Local buffers to hold input dataint A[MAX_SIZE][MAX_SIZE];int B[MAX_SIZE][MAX_SIZE];int C[MAX_SIZE][MAX_SIZE];int temp_sum[MAX_SIZE];// Read data from global memory and write into local buffer for in1
readA:for (int itr = 0, i = 0, j = 0; itr < size * size; itr++, j++) {
#pragma HLS LOOP_TRIPCOUNT min = c_dim* c_dim max = c_dim * c_dimif (j == size) {j = 0;i++;}A[i][j] = in1[itr];}// Read data from global memory and write into local buffer for in2
readB:for (int itr = 0, i = 0, j = 0; itr < size * size; itr++, j++) {
#pragma HLS LOOP_TRIPCOUNT min = c_dim* c_dim max = c_dim * c_dimif (j == size) {j = 0;i++;}B[i][j] = in2[itr];}// Calculate matrix multiplication using local data buffer based on input size,
// and write results into C
count_loop:for (int i = 0; i < rep_count; i++) {nopart1:for (int row = 0; row < size; row++) {
#pragma HLS LOOP_TRIPCOUNT min = c_dim max = c_dimnopart2:for (int col = 0; col < size; col++) {
#pragma HLS LOOP_TRIPCOUNT min = c_dim max = c_dimnopart3:for (int j = 0; j < MAX_SIZE; j++) {
#pragma HLS LOOP_TRIPCOUNT min = c_dim max = c_dimint result = (col == 0) ? 0 : temp_sum[j];result += A[row][col] * B[col][j];temp_sum[j] = result;if (col == size - 1) C[row][j] = result;}}}}// Write results from local buffer to global memory for out
writeC:for (int itr = 0, i = 0, j = 0; itr < size * size; itr++, j++) {
#pragma HLS LOOP_TRIPCOUNT min = c_dim* c_dim max = c_dim * c_dimif (j == size) {j = 0;i++;}out_r[itr] = C[i][j];}
}
}

添加这几行指令:

#pragma HLS ARRAY_PARTITION variable = B dim = 2 complete
#pragma HLS ARRAY_PARTITION variable = C dim = 2 complete
#pragma HLS ARRAY_PARTITION variable = temp_sum dim = 1 complete

运行 Vitis HLS 编译器,我们得到如下结果:

================================================================
== Bind Storage Report
================================================================
+--------------------+------+------+--------+----------+---------+------+---------+
| Name               | BRAM | URAM | Pragma | Variable | Storage | Impl | Latency |
+--------------------+------+------+--------+----------+---------+------+---------+
| + matmul_partition | 1    | 0    |        |          |         |      |         |
|   A_U              | 2    | -    |        | A        | ram_1p  | auto | 1       |
|   B_U              | -    | -    |        | B        | ram_1p  | auto | 1       |
|   B_1_U            | -    | -    |        | B_1      | ram_1p  | auto | 1       |
|   B_2_U            | -    | -    |        | B_2      | ram_1p  | auto | 1       |
|   B_3_U            | -    | -    |        | B_3      | ram_1p  | auto | 1       |
|   B_4_U            | -    | -    |        | B_4      | ram_1p  | auto | 1       |
|   B_5_U            | -    | -    |        | B_5      | ram_1p  | auto | 1       |
|   B_6_U            | -    | -    |        | B_6      | ram_1p  | auto | 1       |
|   B_7_U            | -    | -    |        | B_7      | ram_1p  | auto | 1       |
|   B_8_U            | -    | -    |        | B_8      | ram_1p  | auto | 1       |
|   B_9_U            | -    | -    |        | B_9      | ram_1p  | auto | 1       |
|   B_10_U           | -    | -    |        | B_10     | ram_1p  | auto | 1       |
|   B_11_U           | -    | -    |        | B_11     | ram_1p  | auto | 1       |
|   B_12_U           | -    | -    |        | B_12     | ram_1p  | auto | 1       |
|   B_13_U           | -    | -    |        | B_13     | ram_1p  | auto | 1       |
|   B_14_U           | -    | -    |        | B_14     | ram_1p  | auto | 1       |
|   B_15_U           | -    | -    |        | B_15     | ram_1p  | auto | 1       |
|   C_U              | -    | -    |        | C        | ram_1p  | auto | 1       |
|   C_1_U            | -    | -    |        | C_1      | ram_1p  | auto | 1       |
|   C_2_U            | -    | -    |        | C_2      | ram_1p  | auto | 1       |
|   C_3_U            | -    | -    |        | C_3      | ram_1p  | auto | 1       |
|   C_4_U            | -    | -    |        | C_4      | ram_1p  | auto | 1       |
|   C_5_U            | -    | -    |        | C_5      | ram_1p  | auto | 1       |
|   C_6_U            | -    | -    |        | C_6      | ram_1p  | auto | 1       |
|   C_7_U            | -    | -    |        | C_7      | ram_1p  | auto | 1       |
|   C_8_U            | -    | -    |        | C_8      | ram_1p  | auto | 1       |
|   C_9_U            | -    | -    |        | C_9      | ram_1p  | auto | 1       |
|   C_10_U           | -    | -    |        | C_10     | ram_1p  | auto | 1       |
|   C_11_U           | -    | -    |        | C_11     | ram_1p  | auto | 1       |
|   C_12_U           | -    | -    |        | C_12     | ram_1p  | auto | 1       |
|   C_13_U           | -    | -    |        | C_13     | ram_1p  | auto | 1       |
|   C_14_U           | -    | -    |        | C_14     | ram_1p  | auto | 1       |
|   C_15_U           | -    | -    |        | C_15     | ram_1p  | auto | 1       |
+--------------------+------+------+--------+----------+---------+------+---------+

数组A未指定特定分区,因此将整体存储于单个ram_1p存储器中。而数组B与数组C经过特定设置,按照dim=2的维度被分割为16个区块(即16个ramp_1p存储器),这意味着数组B和数组C能够并行读取16个数据项。此举显著提升了程序处理的吞吐率。

4. 总结

ARRAY_PARTITION指令是高层次综合中一个强大的工具,它可以帮助设计者在保证性能的同时,更有效地利用硬件资源。合理的数组分区可以在不牺牲性能的前提下,优化硬件资源的使用,尤其是在资源受限的设计中。


http://www.ppmy.cn/ops/15646.html

相关文章

基于B2C的网上拍卖系统——秒杀与竞价

点击下载源码和论文https://download.csdn.net/download/liuhaikang/89222887 课题背景及意义 随着网络的进一步普及和电子商务的高速发展&#xff0c;越来越多的人们开始在网络中寻求方便。网上网物具备了省时、省事、省心、高效等特点&#xff0c;从而受到越来越多人的欢迎。…

Flutter 上架如何解决 ITMS-91053 问题

最近&#xff0c;我的 Flutter App 发布到 TestFlight 后&#xff0c;就会收到一封邮件&#xff1a;The uploaded build for YOUR APP has one or more issues. 上面的邮件主要是说&#xff0c;我的 App 缺少了调用 API 的声明&#xff0c;以前从来没看到过&#xff0c;上网一查…

美易官方:人民币国际支付占比升至近5%

随着全球金融市场的不断发展和数字化进程的加速&#xff0c;人民币的国际支付地位逐渐提升&#xff0c;成为备受瞩目的焦点。最近的数据显示&#xff0c;人民币在国际支付中的占比已经升至近5%&#xff0c;自11月以来已成为第四大交易货币。这一变化不仅反映了中国经济的崛起和…

【C++航海王:追寻罗杰的编程之路】C++11(二)

目录 C11(上) 1 -> STL中的一些变化 2 -> 右值引用和移动语义 2.1 -> 左值引用和右值引用 2.2 -> 左值引用与右值引用比较 2.3 -> 右值引用使用场景与意义 2.4 -> 右值引用引用左值及其更深入的使用场景分析 2.5 -> 完美转发 C11(上) 1 -> STL…

mysql 触发器

学习了mysql 视图&#xff0c;接着学习触发器 1&#xff0c;创建触发器 触发器&#xff08;trigger)是个特殊的存储过程&#xff0c;不同的是&#xff0c;执行存储过程要使用CALL语句来调用&#xff0c;而触发器的执行不需要使用CALL语句来调用&#xff0c;也不需要手工启动&am…

数据可视化(四):Pandas技术的高级操作案例,豆瓣电影数据也能轻松分析!

Tips&#xff1a;"分享是快乐的源泉&#x1f4a7;&#xff0c;在我的博客里&#xff0c;不仅有知识的海洋&#x1f30a;&#xff0c;还有满满的正能量加持&#x1f4aa;&#xff0c;快来和我一起分享这份快乐吧&#x1f60a;&#xff01; 喜欢我的博客的话&#xff0c;记得…

《QT实用小工具·四十二》圆形发光图像

1、概述 源码放在文章末尾 该项目实现了图像的发光效果&#xff0c;特别适合做头像&#xff0c;项目demo演示如下所示&#xff1a; 项目部分代码如下所示&#xff1a; import QtQuick 2.7 import QtGraphicalEffects 1.12Item {id: rootwidth: 80height: 80property int ra…

windows下安装es

要安装java 参考文章&#xff1a;JAVA(JDK的下载和安装教程)_java jdk下载-CSDN博客 下载es&#xff1a;Java Downloads | Oracle 中国 cd到es的bin目录&#xff0c;运行 elasticsearch.bat 然后访问。localhos:9200 遇到bug的处理方法&#xff1a;↓ 终端中文乱码的&#x…