Vitis HLS 学习笔记--控制驱动TLP-处理deadlock

目录

1. 简介

2. 代码解析

2.1 HLS kernel代码

2.2 查看接口报告

2.3 TestBench

2.4 Dataflow 报告

3. Takeaways

4. 总结


1. 简介

本文是对《Hardware Acceleration Tutorials: FIFO Sizing for Performance and Avoiding Deadlocks》实验内容的详细解释。

首先需要了解,鉴于数据流优化具有动态特性,且不同并行任务的执行速度各不相同,设置不当的数据流通道可能会引发性能下降或死锁。

数据流通道有两种:FIFO 和 PIPO。可以由工具推断,或者用户自行创建。

FIFO:

  • Streams (including hls::streams and streamed arrays),用户创建。
  • Scalar propagation FIFOs,工具推断。
  • Streams of blocks,用户创建。

每个通道都有自己的握手信号。因为:

  • 它们的读写操作是被调度的。
  • 它们的读/写信号分别由流水线控制或有限状态机(FSM)单独驱动。
  • 它们的full_n/empty_n信号直接使流水线的单个迭代或FSM的状态暂停。

PIPO:

  • PIPO,用户创建。
  • Task Level FIFOs (TLF),工具推断。
  • Input and output ports to the upper level,用户创建。

其中,Task Level FIFOs (TLF) 是标量(scalar)FIFO,其连接到生产者的“done”握手信号以进行写入,并连接到消费者的“start”握手信号以进行读取。这些类型的FIFO是由工具自动推断的。由于底层同步机制的缘故,它们被视为类PIPO。

这些通道应该被视为“使用ap_ctrl_chain握手的通道”,因为:

  • 它们的写入和读取操作不会被调度。它们隐式地与进程的“done”握手或“start”握手相关联。
  • 它们的写入和读取信号分别连接到ap_done和ap_ready。
  • 它们的full_n和empty_n分别连接到ap_continue和ap_start。

总结一下,在分析存储深度、性能、死锁等方面,真正需要关系的是:

  • 通道是否拥有自己的握手机制(FIFOs)。它们的访问在其进程执行期间被分散开来。例如,你可以在管道的第一个II之外读取一个FIFO,或者甚至在数据流网络的最后一个过程中读取。
  • 通道是否通过ap_ctrl_chain进行握手(PIPOs)。它们的读取必须在管道的第一个II中,或者在数据流网络的第一个“层级”的过程中进行,类似地,它们的写入必须在最后一个II或在最后一个“层级”中进行。
  • 另一个区别基于一次操作中传输的数据量,这对于资源分析比对性能分析更为重要:对于PIPOs来说是数组,对于流来说是块流、标量流,对于标量传播FIFOs和任务级FIFOs来说是标量。

2. 代码解析

2.1 HLS kernel代码

#include "example.h"void example(hls::stream<int>& A, hls::stream<int>& B){
#pragma HLS dataflow
#pragma HLS INTERFACE ap_fifo port=A
#pragma HLS INTERFACE ap_fifo port=Bhls::stream<int> data_channel1;hls::stream<int> data_channel2;proc_1(A, data_channel1, data_channel2);proc_2(data_channel1, data_channel2, B);
}void proc_1(hls::stream<int>& A, hls::stream<int>& B, hls::stream<int>& C){
#pragma HLS dataflowhls::stream<int> data_channel1;hls::stream<int> data_channel2;proc_1_1(A, data_channel1, data_channel2);proc_1_2(B, C, data_channel1, data_channel2);
}void proc_1_1(hls::stream<int>& A, hls::stream<int>& data_channel1, hls::stream<int>& data_channel2){int i;int tmp;for(i = 0; i < 10; i++){tmp = A.read();data_channel1.write(tmp); }for(i = 0; i < 10; i++){data_channel2.write(tmp); }
}void proc_1_2(hls::stream<int>& B, hls::stream<int>& C, hls::stream<int>& data_channel1, hls::stream<int>& data_channel2){int i;int tmp;for(i = 0; i < 10; i++){tmp = data_channel2.read() + data_channel1.read();B.write(tmp);}for(i = 0; i < 10; i++){C.write(tmp); }
}void proc_2(hls::stream<int>& A, hls::stream<int>& B, hls::stream<int>& C){
#pragma HLS dataflowhls::stream<int> data_channel1;hls::stream<int> data_channel2;proc_2_1(A, B, data_channel1, data_channel2);proc_2_2(C, data_channel1, data_channel2);
}void proc_2_1(hls::stream<int>& A, hls::stream<int>& B, hls::stream<int>& data_channel1, hls::stream<int>& data_channel2){int i;int tmp;for(i = 0; i < 10; i++){tmp = A.read() + B.read();data_channel1.write(tmp); }for(i = 0; i < 10; i++){data_channel2.write(tmp); }
}void proc_2_2(hls::stream<int>& C, hls::stream<int>& data_channel1, hls::stream<int>& data_channel2){int i;int tmp;for(i = 0; i < 10; i++){tmp = data_channel2.read() + data_channel1.read();C.write(tmp);}
}

与原示例相比,去掉了“&”符号。

#pragma HLS INTERFACE ap_fifo port=&A
#pragma HLS INTERFACE ap_fifo port=&B

以上 kernel 的功能框图:

2.2 查看接口报告

对于顶层文件,可以查看 example_csynth.rpt,观察顶层接口:

================================================================
== Interface
================================================================
* Summary: 
+-----------+-----+-----+------------+--------------+--------------+
| RTL Ports | Dir | Bits|  Protocol  | Source Object|    C Type    |
+-----------+-----+-----+------------+--------------+--------------+
|A_dout     |   in|   32|     ap_fifo|             A|       pointer|
|A_empty_n  |   in|    1|     ap_fifo|             A|       pointer|
|A_read     |  out|    1|     ap_fifo|             A|       pointer|
|B_din      |  out|   32|     ap_fifo|             B|       pointer|
|B_full_n   |   in|    1|     ap_fifo|             B|       pointer|
|B_write    |  out|    1|     ap_fifo|             B|       pointer|
|ap_clk     |   in|    1|  ap_ctrl_hs|       example|  return value|
|ap_rst     |   in|    1|  ap_ctrl_hs|       example|  return value|
|ap_start   |   in|    1|  ap_ctrl_hs|       example|  return value|
|ap_done    |  out|    1|  ap_ctrl_hs|       example|  return value|
|ap_ready   |  out|    1|  ap_ctrl_hs|       example|  return value|
|ap_idle    |  out|    1|  ap_ctrl_hs|       example|  return value|
+-----------+-----+-----+------------+--------------+--------------+

 针对 Dataflow 区域的每个函数体,均有对应的 Interface:

================================================================
== Interface
================================================================
* Summary: 
+-------------------------------+-----+-----+------------+----------------+--------------+
|           RTL Ports           | Dir | Bits|  Protocol  |  Source Object |    C Type    |
+-------------------------------+-----+-----+------------+----------------+--------------+
|ap_clk                         |   in|    1|  ap_ctrl_hs|        proc_1_1|  return value|
|ap_rst                         |   in|    1|  ap_ctrl_hs|        proc_1_1|  return value|
|ap_start                       |   in|    1|  ap_ctrl_hs|        proc_1_1|  return value|
|start_full_n                   |   in|    1|  ap_ctrl_hs|        proc_1_1|  return value|
|ap_done                        |  out|    1|  ap_ctrl_hs|        proc_1_1|  return value|
|ap_continue                    |   in|    1|  ap_ctrl_hs|        proc_1_1|  return value|
|ap_idle                        |  out|    1|  ap_ctrl_hs|        proc_1_1|  return value|
|ap_ready                       |  out|    1|  ap_ctrl_hs|        proc_1_1|  return value|
|start_out                      |  out|    1|  ap_ctrl_hs|        proc_1_1|  return value|
|start_write                    |  out|    1|  ap_ctrl_hs|        proc_1_1|  return value|
|A_dout                         |   in|   32|     ap_fifo|               A|       pointer|
|A_empty_n                      |   in|    1|     ap_fifo|               A|       pointer|
|A_read                         |  out|    1|     ap_fifo|               A|       pointer|
|data_channel12_din             |  out|   32|     ap_fifo|  data_channel12|       pointer|
|data_channel12_num_data_valid  |   in|    2|     ap_fifo|  data_channel12|       pointer|
|data_channel12_fifo_cap        |   in|    2|     ap_fifo|  data_channel12|       pointer|
|data_channel12_full_n          |   in|    1|     ap_fifo|  data_channel12|       pointer|
|data_channel12_write           |  out|    1|     ap_fifo|  data_channel12|       pointer|
|data_channel23_din             |  out|   32|     ap_fifo|  data_channel23|       pointer|
|data_channel23_num_data_valid  |   in|    2|     ap_fifo|  data_channel23|       pointer|
|data_channel23_fifo_cap        |   in|    2|     ap_fifo|  data_channel23|       pointer|
|data_channel23_full_n          |   in|    1|     ap_fifo|  data_channel23|       pointer|
|data_channel23_write           |  out|    1|     ap_fifo|  data_channel23|       pointer|
+-------------------------------+-----+-----+------------+----------------+--------------+

上述报告 Source  Object 所在列:

  • A - > hls::stream<int>& A, C type 为 pointer
  • data_channel12 -> hls::stream<int>& data_channel1, C type 为 pointer
  • data_channel23 -> hls::stream<int>& data_channel2, C type 为 pointer
​
void proc_1_1(hls::stream<int>& A, hls::stream<int>& data_channel1, hls::stream<int>& data_channel2){int i;int tmp;for(i = 0; i < 10; i++){tmp = A.read();data_channel1.write(tmp);}for(i = 0; i < 10; i++){data_channel2.write(tmp);}
}

2.3 TestBench

#include <stdio.h>
#include "hls_stream.h"#define SIZE 10
extern void example(hls::stream<int>& A, hls::stream<int>& B);int main()
{int i;hls::stream<int> A;hls::stream<int> B;int time = 0;for   (time = 0 ; time < 4; time ++) {for(i=0; i < SIZE; i++){A << (i + time);}example(A,B);}return 0;
}

2.4 Dataflow 报告

运行 C Synthesis 后,可以查看 Dataflow 报告,如下图,没有问题。

在运行 C/RTL Cosimulation 后,同样在 Dataflow 报告中可以看到错误。

3. Takeaways

总结而言,Dataflow查看器实现了以下吞吐量分析任务:

图表展示了 DATAFLOW 区域的整体拓扑结构,并显示了在 DATAFLOW 区域中任务之间用于通信的通道类型(FIFO/PIPO)。通过分析每个通道和进程,可以有效地解决死锁或由于FIFO大小不当导致的吞吐量不足等问题。

协同仿真数据通过在仿真过程中跟踪FIFO的最大使用量,为解决FIFO大小设置问题提供了参考依据,从而帮助用户调整FIFO大小。此外,运行协同仿真时的自动死锁检测功能能够突出显示涉及死锁的进程和通道,使用户能够快速定位并解决这些问题。

除了 FIFO 大小的调整,协同仿真后的数据还能按每个进程和通道报告因等待输入或输出而导致的停滞时间。这些图表帮助用户理解并解决这些问题,同时管理通道大小以满足慢速生产者与快速消费者之间的需求,或者相反。此外,图表还揭示了在DATAFLOW区域中途读取输入如何影响整体性能,这是一个常见的场景,可能会对性能产生重大影响。

4. 总结

在数据流优化中,通道类型、握手机制、FIFO大小和死锁避免都是关键因素。通过Dataflow查看器和协同仿真数据,您可以有效地优化设计,提高性能并避免潜在问题。

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

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

相关文章

自动驾驶场景中的长尾问题怎么解决?

自动驾驶长尾问题是指自动驾驶汽车中的边缘情况&#xff0c;即发生概率较低的可能场景。感知的长尾问题是当前限制单车智能自动驾驶车辆运行设计域的主要原因之一。自动驾驶的底层架构和大部分技术问题已经被解决&#xff0c;剩下的5%的长尾问题&#xff0c;逐渐成了制约自动驾…

huggingface 笔记:查看GPU占用情况

0 准备部分 0.1 创建虚拟数据 import numpy as npfrom datasets import Datasetseq_len, dataset_size 512, 512 dummy_data {"input_ids": np.random.randint(100, 30000, (dataset_size, seq_len)),"labels": np.random.randint(0, 1, (dataset_size…

【代码随想录训练营】【Day 29】【回溯-3】| Leetcode 39, 41, 131

【代码随想录训练营】【Day 29】【回溯-3】| Leetcode 39&#xff0c; 41&#xff0c; 131 需强化知识点 startInex作用&#xff1a;一是处理是否可以有重复值&#xff0c;二是实现纵向遍历&#xff08;不能没有&#xff09;去重要在数组有序的前提下进行分割问题 题目 39.…

工业控制2D组态界面,丑是丑了点,但非常实用。

工业控制的2D组态界面是用于监控和控制工业过程的界面。它通常具有以下特征&#xff1a; 实时数据显示&#xff1a;2D组态界面能够实时显示传感器和设备的数据&#xff0c;如温度、压力、流量等。这些数据以图表、仪表盘、数字显示等形式呈现&#xff0c;使操作人员能够实时了解…

Android:使用Kotlin搭建MVVM架构模式

一、简介Android MVVM架构模式 MVVM全称&#xff1a;Model、View、ViewModel&#xff1b; Model&#xff1a;负责数据的请求、解析、过滤等数据层操作&#xff0c;其中Repository: 提供数据的 API&#xff08;从本地或者网络&#xff09;。View&#xff1a;负责视图部分展示Vie…

快速幂求逆元与逆元

我上一篇博客链接写的是多个数求乘法逆元而快速幂求逆元用于单个数求乘法逆元 逆元是对分数取模用的 对于除法取模不成立&#xff0c;即(a/b)%p≠(a%p/b%p)%p。求逆元的思路&#xff1a;(一般ACM的题目都是对1e97这种素数取模&#xff0c;所以gcd(a,p)1)a*b1(mod p) > b1/a…

[Algorithm][动态规划][简单多状态DP问题][按摩师][打家劫舍Ⅱ][删除并获得点数][粉刷房子]详细讲解

目录 1.按摩师1.题目链接2.算法思路详解3.代码实现 2.打家劫舍 II1.题目链接2.算法思路详解3.代码实现 3.删除并获得点数1.题目链接2.算法思路详解3.代码实现 4.粉刷房子1.题目链接2.算法思路详解3.代码实现 1.按摩师 1.题目链接 按摩师 2.算法思路详解 思路&#xff1a; 确…

大模型提示词Prompt学习

引言 关于chatGPT的Prompt Engineer&#xff0c;大家肯定耳朵都听起茧了。但是它的来由&#xff1f;&#xff0c;怎么能用好&#xff1f;很多人可能并不觉得并不是一个问题&#xff0c;或者说认定是一个很快会过时的概念。但其实也不能说得非常清楚&#xff08;因为觉得没必要深…

Redis第18讲——Redis和Redission实现延迟消息

即使不是做电商业务的同学&#xff0c;也一定知道订单超时关闭这种业务场景&#xff0c;这个场景大致就是用户下单后&#xff0c;如果在一定时间内未支付&#xff08;比如15分钟、半小时&#xff09;&#xff0c;那么系统就会把这笔订单给关闭掉。这个功能实现的方式有很多种&a…

unity开发Hololens 制作滑动框

一定要做到最后一步&#xff0c;才会有效果 1、创建空物体 ,并添加组件 创建空物体 命名ScrollingObjectCollection&#xff0c; 添加组件如下图 下面是各个组件展开的内容 2、在ScrollingObjectCollection 下面创建两个空物体&#xff0c;分别命名Container、Clipping…

运筹说 第115期 | 排队论经典例题讲解

通过前几期的学习&#xff0c;我们已经学会了排队论的基本概念、生灭过程和Poisson过程&#xff0c;等待制排队模型、混合制排队模型、其他排队模型以及排队系统优的定义与相关求解方法。在实际工作中&#xff0c;我们能发现排队论在经济管理中有着许多应用&#xff0c;本期小编…

大数据量上传FTP

背景 笔者有一个需求是把将近一亿条数据上传到FTP服务器中&#xff0c;这些数据目前是存储在mysql中&#xff0c;是通过关联几张表查询出来的&#xff0c;查询出来的数据结果集一共是6个字段。要求传输的时候拆分成一个个小文件&#xff0c;每个文件大小不能超过500M。我的测试…

FuTalk设计周刊-Vol.052

#AI漫谈 热点捕手 1.ChatGPT 大更新&#xff01;GPT-4 开始又变聪明了 OpenAI 官方宣布&#xff0c;新版 GPT-4 Turbo 今天开始向所有付费 ChatGPT 用户开放。 链接https://www.pconline.com.cn/focus/1733/17330089.html 2.刷爆多模态任务榜单&#xff01;贾佳亚团队Mini-G…

21.2zabbix低级自动发现-mysql多实例

配置mysql多实例 注释&#xff1a;自动发现&#xff1a;创建监控主机&#xff1b;低级自动发现&#xff1a;创建监控项 mysql单实例是直接yum安装&#xff0c;开启mysql多实例 准备配置文件 #mysql3307实例 cp /etc/my.cnf /etc/my3307.cnf vim /etc/my3307.cnf [mysqld] dat…

产品经理-流程图结构图(四)

1. 流程图 1.1 概念 为了达到特定的目标而进行的一系列有逻辑性的操作步骤&#xff0c;由两个及以上的步骤&#xff0c;完成一个完整的行为的过程&#xff0c;可称之为流程 1.2 产品经理为什么需要绘制流程图&#xff1f; 保证产品的使用逻辑合理顺畅向项目组其他成员清晰的…

代码随想录算法训练营Day4|24. 两两交换链表中的节点、19.删除链表的倒数第N个节点、 142.环形链表II、面试题 02.07. 链表相交

24. 两两交换链表中的节点 这道题的关键在于: 1、在置换两个节点的时候&#xff0c;当前节点需要在这俩节点之前一个节点。并且要提前保存cur.next以及cur.next.next。 2、每次置换完一组节点&#xff0c;cur cur.next.next 3、判断结束的标志&#xff1a;奇数个节点&#xf…

如何禁止U盘拷贝文件|禁止U盘使用的软件有哪些

禁止U盘拷贝文件的方法有很多&#xff0c;比如使用注册表、组策略编辑器等&#xff0c;但这些方法都适合个人&#xff0c;不适合企业&#xff0c;因为企业需要对下属多台电脑进行远程管控&#xff0c;需要方便、省时、省力的方法。目前来说&#xff0c;最好的方法就是使用第三方…

技术速递|无障碍应用程序之旅:键盘可访问性和 .NET MAUI

作者&#xff1a;Rachel Kang 排版&#xff1a;Alan Wang 首先让我们一起来看看您的应用程序是否支持键盘访问&#xff1a; 启动您的其中一个应用。如果您的设备尚未连接物理键盘&#xff0c;请连接物理键盘。像平常一样导航您的应用程序&#xff0c;并且仅使用键盘来执行此操…

如何使用Rust构建Python原生库?注意,不是动态链接库!!!

参考文档&#xff1a;https://github.com/PyO3/pyo3 创建python虚拟环境&#xff1a; conda create --name pyo3 python3.11.7激活虚拟环境&#xff1a; conda activate pyo3安装依赖&#xff1a; pip install maturin初始化项目&#xff1a; maturin init构建项目&#x…

小程序checkbox改成圆形与radio样式保持一致

修改前 修改后 html: <view class"agreement"><checkbox value"{{ isAgreed }}" bind:tap"toggleCheckbox" /><text>我同意室外智能健身房 <text class"link" bind:tap"showUserProtocol">用户协…