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

目录

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.hqwc.cn/news/640681.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

使用 OpenCV 测量物体尺寸

使用 OpenCV 测量物体尺寸 你是否曾经遇到过这样的问题&#xff1a;想要知道计算器的精确尺寸&#xff0c;但手头又没有专业的测量工具&#xff1f;别担心&#xff0c;今天我们就来教大家一个简单又实用的方法&#xff0c;通过一张A4纸就能估算出计算器的宽度和高度&#xff0c…

了解边缘计算,在制造行业使用边缘计算。

边缘计算是一种工业元宇宙技术&#xff0c;可以帮助组织实现其数据的全部潜力。 处理公司的所有数据可能具有挑战性&#xff0c;而边缘计算可以帮助公司更快地处理数据。在制造业中&#xff0c;边缘计算可以帮助进行预测性维护和自动驾驶汽车操作等工作。 什么是边缘计算? …

CMake 编译项目

一、概述 cmake 是C一个很重要的编译和项目管理工具&#xff0c;我们在git 上以及常见的项目现在多数都是用cmake 管理的&#xff0c;那么我们今天就做一个同时有Opencv和CGAL 以及PCL 的项目。 二、项目管理 重点是CMakeList.txt 1、CMakeList.txt cmake_minimum_requir…

FebHost:CO域名在搜索引擎排名中是否高于.COM域名?

.CO 域名在搜索引擎结果中有可能取得高于 .COM 域名的排名&#xff0c;但要注意的是&#xff0c;域名的后缀本身并不会直接影响其搜索排名。决定网站在搜索引擎中的排名的主要因素是搜索引擎优化&#xff08;SEO&#xff09;实践的有效性&#xff0c;包括内容的质量、关键词的使…

Quarto Dashboards 教程 2:Dashboard Layout

「写在前面」 学习一个软件最好的方法就是啃它的官方文档。本着自己学习、分享他人的态度&#xff0c;分享官方文档的中文教程。软件可能随时更新&#xff0c;建议配合官方文档一起阅读。推荐先按顺序阅读往期内容&#xff1a; 1.quarto 教程 1&#xff1a;Hello, Quarto 2.qu…

医学影像图像去噪:滤波器方法、频域方法、小波变换、非局部均值去噪、深度学习与稀疏表示和字典学习

医学影像图像去噪是指使用各种算法从医学成像数据中去除噪声,以提高图像质量和对疾病的诊断准确性。MRI(磁共振成像)和CT(计算机断层扫描)是两种常见的医学成像技术,它们都会受到不同类型噪声的影响。 在医学影像中,噪声可能来源于多个方面,包括成像设备的电子系统、患…

支持中文繁体,支持同时配置并启用飞书和Lark认证,JumpServer堡垒机v3.10.8 LTS版本发布

2024年4月22日&#xff0c;JumpServer开源堡垒机正式发布v3.10.8 LTS版本。JumpServer开源项目组将对v3.10 LTS版本提供长期的支持和优化&#xff0c;并定期迭代发布小版本。欢迎广大社区用户升级至v3.10 LTS最新版本&#xff0c;以获得更佳的使用体验。 在v3.10.8 LTS版本中&…

java-Arrays

一、Arrays的概述 Arrays是操作数组的工具类 二、Arrays的常用方法 Arrays的常用方法基本上都被static静态修饰&#xff0c;因此在使用这些方法时&#xff0c;可以直接通过类名调用 1.toString 语法&#xff1a;Arrays.toString(数组) 用于将数组的元素转换为一个字符串&a…

分享三个转换速度快、准确率高的视频转文字工具

想要直接将视频转换成文字&#xff0c;转换工具很重要&#xff01;给大家分享三个转换速度快、准确率高的视频转文字工具&#xff0c;轻松完成转换。 1.网易见外 https://sight.youdao.com/ 网易家的智能转写翻译服务工作站&#xff0c;网页端就可以直接使用&#xff0c;支持视…

ubuntu apt update:The repository ‘xxx‘ is not signed.报错解决办法(未解决)

文章目录 报错原因及解决办法 报错 rootjax:~# apt update Get:1 file:/var/cuda-repo-l4t-11-4-local InRelease [1575 B] Get:2 file:/var/cudnn-local-repo-ubuntu2004-8.4.1.50 InRelease [1575 B] Get:1 file:/var/cuda-repo-l4t-11-4-local InRelease [1575 B] Get:2 …

[图解]软件开发中的糊涂用语-04-为什么要追究糊涂用语

0 00:00:00,030 --> 00:00:05,620 今天呢&#xff0c;我们来说一个为什么要追究糊涂用语的问题 1 00:00:06,310 --> 00:00:06,548 2 00:00:06,548 --> 00:00:11,077 大家知道我们前些天都发了好几个视频 3 00:00:11,077 --> 00:00:13,461 追究这个糊涂用语 4 00…

COCONut:打造下一代通用分割数据集,重塑计算机视觉基准

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…