Vitis HLS 学习笔记--优化循环启动间隔(II)

目录

1. 概述

2. 常规矩阵乘法

3. 数据依赖性和内存访问模式

4. 优化循环

5. 总结


1. 概述

Initiation Interval(II)定义为启动连续操作之间的时间间隔,以时钟周期为单位。低的II是高性能和高资源利用率的关键。

较高的II意味着在单位时间内完成的操作数量减少,从而降低了整体的吞吐量,部分硬件资源(如加法器、乘法器等)会闲置,没有被充分利用。

2. 常规矩阵乘法

矩阵乘法定义如下:

{\displaystyle (AB)_{ij}=\sum _{r=1}^{n}a_{ir}b_{rj}=a_{i1}b_{1j}+a_{i2}b_{2j}+\cdots +a_{in}b_{nj}}

 前两层循环,遍历所有元素,第三层循环,用于元素累加乘,代码如下:

for (int i = 0; i < size; i++)
{for (int j = 0; j < size; j++){for (int k = 0; k < MAX_SIZE; k++){int result = (k == 0) ? 0 : temp_sum[j];result += A[i][k] * B[k][j];temp_sum[j] = result;if (k== size -1) C[i][j] = result;}}
}

对于矩阵A和矩阵B的乘积,每个输出元素C[i][j]是通过将A矩阵的第i行与B矩阵的第j列对应元素相乘然后加总得到的,这意味着在计算C[i][j]的每个元素时,都需要访问A[i][k]和B[k][j]。

3. 数据依赖性和内存访问模式

由于B矩阵的访问是按列进行的,这不是连续的内存访问,会导致缓存利用率低下。

同时,HLS编译器会构建一个加法器树来逐步累加每次乘法的结果。由于每次循环迭代都依赖于前一次的结果,也会导致较高的Initiation Interval(II)。

+-----------------------+---------+---------+----------+-----------+-----------+------+----------+
|                       |  Latency (cycles) | Iteration|  Initiation Interval  | Trip |          |
|       Loop Name       |   min   |   max   |  Latency |  achieved |   target  | Count| Pipelined|
+-----------------------+---------+---------+----------+-----------+-----------+------+----------+
|- lreorder1_lreorder2  |        ?|        ?|        33|         32|          1|     ?|       yes|
+-----------------------+---------+---------+----------+-----------+-----------+------+----------+

 从编译器反馈的结果来看,II=32,每32个时钟周期就可以启动一个新的迭代。

================================================================
== Utilization Estimates
================================================================
* Summary: 
+-----------------+---------+------+--------+--------+-----+
|       Name      | BRAM_18K|  DSP |   FF   |   LUT  | URAM|
+-----------------+---------+------+--------+--------+-----+
|DSP              |        -|     -|       -|       -|    -|
|Expression       |        -|     -|       0|    1813|    -|
|FIFO             |        -|     -|       -|       -|    -|
|Instance         |        -|    96|       0|    5376|    -|
|Memory           |        -|     -|       -|       -|    -|
|Multiplexer      |        -|     -|       -|   10137|    -|
|Register         |        -|     -|    2302|       -|    -|
+-----------------+---------+------+--------+--------+-----+
|Total            |        0|    96|    2302|   17326|    0|
+-----------------+---------+------+--------+--------+-----+
|Available        |      288|  1248|  234240|  117120|   64|
+-----------------+---------+------+--------+--------+-----+
|Utilization (%)  |        0|     7|      ~0|      14|    0|
+-----------------+---------+------+--------+--------+-----+

 对于这些硬件资源,它们在大部分时间内处于空闲状态,硬件的潜在计算能力没有得到充分发挥。

4. 优化循环

 优化后的代码:

for (int i = 0; i < size; i++) {for (int k = 0; k < size; k++) {for (int j = 0; j < size; j++) {int result = (k == 0) ? 0 : temp_sum[j];result += A[i][k] * B[k][j];temp_sum[j] = result;if (k == size - 1) C[i][j] = result;}}
}

通过将k循环移到中间层,改变了内存访问的模式。现在,对B[k][j]的访问变得连续,因为j循环是最内层。

同时,由于result的计算不再依赖于k循环的前一次迭代结果,因此可以减少依赖性。

+-----------------------+---------+---------+----------+-----------+-----------+------+----------+
|                       |  Latency (cycles) | Iteration|  Initiation Interval  | Trip |          |
|       Loop Name       |   min   |   max   |  Latency |  achieved |   target  | Count| Pipelined|
+-----------------------+---------+---------+----------+-----------+-----------+------+----------+
|- lreorder1_lreorder2  |     1024|     1024|         2|          1|          1|  1024|       yes|
+-----------------------+---------+---------+----------+-----------+-----------+------+----------+

同时减少了资源占用:

================================================================
== Utilization Estimates
================================================================
* Summary: 
+-----------------+---------+------+--------+--------+-----+
|       Name      | BRAM_18K|  DSP |   FF   |   LUT  | URAM|
+-----------------+---------+------+--------+--------+-----+
|DSP              |        -|     -|       -|       -|    -|
|Expression       |        -|     -|       0|    2593|    -|
|FIFO             |        -|     -|       -|       -|    -|
|Instance         |        -|    96|       0|     640|    -|
|Memory           |        -|     -|       -|       -|    -|
|Multiplexer      |        -|     -|       -|      54|    -|
|Register         |        -|     -|    1190|       -|    -|
+-----------------+---------+------+--------+--------+-----+
|Total            |        0|    96|    1190|    3287|    0|
+-----------------+---------+------+--------+--------+-----+
|Available        |      288|  1248|  234240|  117120|   64|
+-----------------+---------+------+--------+--------+-----+
|Utilization (%)  |        0|     7|      ~0|       2|    0|
+-----------------+---------+------+--------+--------+-----+

5. 总结

循环重排优化了内存访问模式,减少了数据依赖性,使得硬件能够更有效地并行处理计算,从而提高了执行效率。II从32降低到了1。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/818340.shtml

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

相关文章

使用DockerCompose配置基于哨兵模式的redis主从架构集群

文章目录 一、注意事项&#xff08;坑点&#xff01;&#xff01;&#xff01;&#xff09;二、配置Redis主从架构集群第一步&#xff1a;创建目录文件结构第二步&#xff1a;编写DockerCompose配置文件第三步&#xff1a;编写redis.conf第四步&#xff1a;启动redis主从集群 三…

CentOS如何使用Docker部署Plik服务并实现公网访问本地设备上传下载文件

文章目录 1. Docker部署Plik2. 本地访问Plik3. Linux安装Cpolar4. 配置Plik公网地址5. 远程访问Plik6. 固定Plik公网地址7. 固定地址访问Plik 本文介绍如何使用Linux docker方式快速安装Plik并且结合Cpolar内网穿透工具实现远程访问&#xff0c;实现随时随地在任意设备上传或者…

C语言 递归

递归指的是在函数的定义中使用函数自身的方法。 举个例子&#xff1a; 从前有座山&#xff0c;山里有座庙&#xff0c;庙里有个老和尚&#xff0c;正在给小和尚讲故事呢&#xff01;故事是什么呢&#xff1f;“从前有座山&#xff0c;山里有座庙&#xff0c;庙里有个老和尚&…

蓝桥杯-阿坤老师的魔方挑战

图示: 代码: #include <iostream> using namespace std; int main() {int N,i,j,row,col,sum,max0;cin>>N;int ar[N][N];for(i0;i<N;i){for(j0;j<N;j){cin>>ar[i][j];}//输入矩阵 }for(i0;i<N;i){row0;coli;sum0;//重新初始化while(row<N){if(c…

初识集合框架

前言~&#x1f973;&#x1f389;&#x1f389;&#x1f389; hellohello~&#xff0c;大家好&#x1f495;&#x1f495;&#xff0c;这里是E绵绵呀✋✋ &#xff0c;如果觉得这篇文章还不错的话还请点赞❤️❤️收藏&#x1f49e; &#x1f49e; 关注&#x1f4a5;&#x1f…

eclipse导入maven项目与配置使用本地仓库

前言 本人润国外了&#xff0c;发现不能用收费软件IDEA了&#xff0c;需要使用eclipse&#xff0c;这个免费。 但是早忘了怎么用了&#xff0c;在此总结下。 一、eclipse导入本地项目 1.选这个&#xff1a;open projects from file system… 2.找到项目文件夹&#xff0c;…

借力社交裂变,Xinstall助你实现用户快速增长

在数字化时代&#xff0c;社交裂变已成为品牌获取新用户、扩大影响力的关键手段。然而&#xff0c;如何有效利用社交裂变&#xff0c;实现用户快速增长&#xff0c;却是许多品牌面临的挑战。今天&#xff0c;我们将为大家介绍一个强大的社交裂变引擎——Xinstall&#xff0c;它…

Python中sort()函数、sorted()函数的用法深入讲解(具体实例:蓝桥杯数位排序)

前置知识&#xff1a; 可迭代对象的定义&#xff1a;可迭代对象是指可以被迭代或遍历的对象&#xff0c;即可以使用循环结构对其进行逐个访问的对象。 在Python中常见的可迭代对象有&#xff1a;列表(list)、元组&#xff08;tuple&#xff09;、字符串&#xff08;sting&…

基于SpringBoot+Vue实现的医院在线挂号系统(代码+万字文档)

系统介绍 基于SpringBootVue实现的医院在线挂号系统设计了三种角色&#xff0c;分别是管理员、医生、用户&#xff0c;每种角色对应不同的菜单 系统实现了个人信息管理、基础数据管理、论坛管理、用户管理、单页数据管理、医生管理及轮播图管理等功能模块&#xff0c;具体功能…

【大语言模型】基础:如何处理文章,向量化与BoW

词袋模型&#xff08;BoW&#xff09;是自然语言处理&#xff08;NLP&#xff09;和机器学习中一种简单而广泛使用的文本表示方法。它将文本文档转换为数值特征向量&#xff0c;使得可以对文本数据执行数学和统计操作。词袋模型将文本视为无序的单词集合&#xff08;或“袋”&a…

React 集成三方登录按钮样式的插件库

按钮不提供任何社交逻辑。 效果如下&#xff1a; 原地址&#xff1a;https://www.npmjs.com/package/react-social-login-buttons 时小记&#xff0c;终有成。

【C++成长记】C++入门 | 类和对象(中) |拷贝构造函数、赋值运算符重载、const成员函数、 取地址及const取地址操作符重载

&#x1f40c;博主主页&#xff1a;&#x1f40c;​倔强的大蜗牛&#x1f40c;​ &#x1f4da;专栏分类&#xff1a;C❤️感谢大家点赞&#x1f44d;收藏⭐评论✍️ 目录 一、拷贝构造函数 1、概念 2、特征 二、赋值运算符重载 1、运算符重载 2、赋值运算符重载 3、前置…

G2D图像处理硬件调用和测试-基于米尔-全志T113-i开发板

本篇测评由电子工程世界的优秀测评者“jf_99374259”提供。 本文将介绍基于米尔电子MYD-YT113i开发板的G2D图像处理硬件调用和测试。 MYC-YT113i核心板及开发板 真正的国产核心板&#xff0c;100%国产物料认证 国产T113-i处理器配备2*Cortex-A71.2GHz &#xff0c;RISC-V 外置…

SpringBoot启动流程分析之准备应用上下文refreshContext()

文章目录 源码入口1、准备刷新1.1、子类prepareRefresh()方法1.2 父类prepareRefresh&#xff08;&#xff09;方法 2、通知子类刷新内部bean工厂3、准备bean工厂4、允许上下文子类对bean工厂进行后置处理 源码入口 org.springframework.boot.SpringApplication#run(java.lang…

若依vue中关于字典的使用

文章目录 字典管理页面列表点击某个字典类型展示具体字典数据修改某一条字典数据 字典的应用一般用于select多选框中代码实现根据字典Dict的value获取Label&#xff0c;类似于通过key获得value 源码解析 字典管理页面 列表 点击某个字典类型展示具体字典数据 修改某一条字典数…

Zookeeper集群+消息队列Kafka

一. Zookeeper 集群的相关知识 1. zookeeper的概念 ZooKeeper 是一个分布式的&#xff0c;开放源码的分布式应用程序协调服务&#xff0c;是Google的Chubby一个开源的实现&#xff0c;是Hadoop和Hbase的重要组件。它是一个为分布式应用提供一致性服务的软件&#xff0c;提供的…

C++修炼之路之list模拟实现--C++中的双向循环链表

目录 引言 一&#xff1a;STL源代码中关于list的成员变量的介绍 二&#xff1a;模拟实现list 1.基本结构 2.普通迭代器 const迭代器的结合 3.构造拷贝构造析构赋值重载 清空 4.inserterase头尾插入删除 5.打印不同数据类型的数据《使用模板加容器来完成》 三&#xf…

python之gmsh划分网格

Gmsh&#xff08;Geometry Modeling and Meshing Suite&#xff09;是一个开源的三维有限元网格生成器&#xff0c;它集成了内置的CAD引擎和后处理器。Gmsh的设计目标是提供一个快速、轻量级且用户友好的网格工具&#xff0c;同时具备参数化输入和高级可视化能力。Gmsh围绕几何…

数据治理项目——深铁集团数据治理规划

目录 一、前言 二、数据治理内容与主要措施 2.1 实施背景 2.2 主要举措 2.2.1 制定数据战略目标 2.2.2 绘制数据治理蓝图 2.2.3 绘制数据治理制度 2.2.4 梳理数据资产目录 三、 应用效果 3.1 数据资产可视化管理 3.2 数据标准治理 3.3 集团大数据平台优化建设 一、…

Windows10为Git Bash添加文件传输命令rsync(详细图文配置)

文章目录 1. 安装git bash2. 下载所需要的4个包3. 下载解压包的软件4. 复制每个包下面的usr到git安装目录下4.1 所遇问题4.2 解决 5. 安装完成6. 需要注意 Windows上要使用 rsync命令上传或下载文件&#xff0c;需要使用git bash&#xff0c;git bash没有rsync&#xff0c;需要…