从FPGA说起的深度学习(六)-任务并行性

7229a341964de7d359d7878d5bbf4854.png

这是新的系列教程,在本教程中,我们将介绍使用 FPGA 实现深度学习的技术,深度学习是近年来人工智能领域的热门话题。

在本教程中,旨在加深对深度学习和 FPGA 的理解。

  • 用 C/C++ 编写深度学习推理代码

  • 高级综合 (HLS) 将 C/C++ 代码转换为硬件描述语言

  • FPGA 运行验证

3f90ad3f61ade79aa2409277dbad309b.png

从这篇文章中,我们将从之前创建的网络模型中提取并行性,并确认处理速度得到了提高。首先,我们检查当前模型的架构,并考虑什么样的并行化是可性的。

并行化方法研究

当前模型架构的框图如下所示。限于篇幅省略了maxpool2d和relu。

2459e76ed484062a5fa0fc19ae50308a.png

在这个模块中,conv1、conv2、fc1、fc2都是作为不同的模块实现的。FPGA内部的SRAM在每一层之间插入一个缓冲区(x', x'', x''' ),这个缓冲区成为每一层的输入和输出。此后,每一层(conv1、conv2、fc1、fc2)被称为一个任务。

顺序处理(基线)

下图显示了使用该模块对 3 帧图像执行推理处理时的执行时间可视化。

每个任务的执行时间以推理模块的实际运行波形为准,是conv2>conv1>fc1>fc2的关系。在该模块中,conv1、conv2、fc1和fc2作为单独的任务实施,但是这些任务一次只能运行一个(后面会解释原因)。因此,如果将conv1、conv2、fc1、fc2各层的执行时间作为最终的执行时间,则这3帧图像的t0, t1, t2, t3处理时间为3 * (t0 + t1 + t2 + t3)

c3949e7777d83e10d6b1435e015e920f.png

任务并行度

假设我们可以修复这些任务并发运行。这种情况下的执行时间如下所示,多个任务可以同时处理不同的帧。

893e9abedbd9661d9753cf81ff5f0676.png

提取并行性使多个任务可以同时运行,称为任务并行化。在这个过程中,conv2的执行时间占主导地位,所以3帧的处理时间为t0 + 3 * t1 + t2 + t3。

理想的任务并行度

最后,我们考虑可以理想地执行任务并行化的模式。如上所述,如果只提取任务并行性,最慢的任务就会成为瓶颈,整体处理速度会受到该任务性能的限制。因此,最有效的任务并行是所有任务都具有相同的执行时间。

8943d3b8d492f3873bba5da61686e15b.png

在这种情况下,处理时间t0 + 3 * t1 + t2 + t3保持不变,但t0 = t1 = t2 = t3调整了每个任务的执行时间,从而提高了性能。在本课程中,实现这种加速的技术被称为循环并行化和数据并行化。这两种并行度提取方法将在下一篇文章中介绍。

任务并行化

在本文中,第一个目标是执行任务并行化。

由于这次创建的模块中有多个任务,貌似已经可以并行处理了,但在实际波形中并不是这样。之所以不能并行化,是因为作为x', x'', x'''任务间接口的buffer()不能被多个任务同时使用。对于任务并行化,任务之间的接口必须可以同时被两个或多个任务读写。

在这个模块x'中,任务级并行化是通过在任务之间使用乒乓缓冲区来实现的。乒乓缓冲区有两个缓冲区,一个用于写入,一个用于读取。带有乒乓缓冲器的框图如下所示:

a80c76ad7277e60fe05c9abed4784c56.png带有乒乓缓冲器的推理模块

如果以这种方式配置电路,存储 conv1 输出的缓冲区和 conv2 从中读取输入的缓冲区是分开的,因此 conv1 和 conv2 可以同时运行。虽然图中省略了,但所有层都可以通过双缓冲conv2 <-> fc1,fc1 <-> fc2同时操作。

要在 RTL 中实现这一点,准备两个缓冲区并实现切换机制会很麻烦,但在 Vivado/Vitis HLS 中,只需添加一些 pragma 即可实现这种并行化。

代码更改

对于此任务并行化,我们需要添加以下三种类型的编译指示。

#pragma HLS dataflow
#pragma HLS stable
#pragma HLS interface ap_ctrl_chain

在解释每个pragma的作用之前,我先inference_dataflow展示一下新增函数的源代码。与第五篇中的inference_top函数重叠的部分省略。

60 void inference_dataflow(const float x[kMaxSize],
 61                         const float weight0[kMaxSize], const float bias0[kMaxSize],
 62                         const float weight1[kMaxSize], const float bias1[kMaxSize],
 63                         const float weight2[kMaxSize], const float bias2[kMaxSize],
 64                         const float weight3[kMaxSize], const float bias3[kMaxSize],
 65                         float y[kMaxSize]) {
 66 #pragma HLS dataflow
 67 #pragma HLS interface m_axi port=x offset=slave bundle=gmem0
 ...
 76 #pragma HLS interface m_axi port=y offset=slave bundle=gmem9
 77 #pragma HLS interface s_axilite port=x bundle=control
 ...
 86 #pragma HLS interface s_axilite port=y bundle=control
 87 #pragma HLS interface s_axilite port=return bundle=control
 88 #pragma HLS interface ap_ctrl_chain port=return bundle=control
 89
 90 #pragma HLS stable variable=x
 91 #pragma HLS stable variable=weight0
 92 #pragma HLS stable variable=bias0
 93 #pragma HLS stable variable=weight1
 94 #pragma HLS stable variable=bias1
 95 #pragma HLS stable variable=weight2
 96 #pragma HLS stable variable=bias2
 97 #pragma HLS stable variable=weight3
 98 #pragma HLS stable variable=bias3
 99 #pragma HLS stable variable=y
100
101   dnnk::inference(x,
102                   weight0, bias0,
103                   weight1, bias1,
104                   weight2, bias2,
105                   weight3, bias3,
106                   y);
107 }

第66 行添加#pragma HLS dataflow的 pragma使inference_dataflow这些内部函数之间的接口成为乒乓缓冲区并启用任务并行化。第 101 行调用的函数dnnk::inference是下面的函数,它通过第 20 行的#pragma HLS inline编译指示在函数内inference_dataflow内嵌展开。因此,诸如 conv2d, relu的函数符合任务并行化的条件,它们的接口 ( x1, x2, ...) 是一个乒乓缓冲区。

14 static void inference(const float* x,
 15                       const float* weight0, const float* bias0,
 16                       const float* weight1, const float* bias1,
 17                       const float* weight2, const float* bias2,
 18                       const float* weight3, const float* bias3,
 19                       float* y) {
 20 #pragma HLS inline
 ...
 34
 35   // 1st layer
 36   conv2d(x, weight0, bias0, kWidths[0], kHeights[0], kChannels[0], kChannels[1], 3, x1);
 37   relu(x1, kWidths[0] * kHeights[0] * kChannels[1], x2);
 38   maxpool2d(x2, kWidths[0], kHeights[0], kChannels[1], 2, x3);
 39
 ...
 48
 49   // 4th layer
 50   linear(x8, weight3, bias3, kChannels[3], kChannels[4], y);
 51 }

inference_dataflow从函数的第90行#pragma HLS stable开始,在x, weight0, y输入/输出等函数inference_dataflow的入口/出口处自动完成同步。如果不去掉这个同步,两个进程之间就会产生依赖,比如“上一帧y输出完成->下一帧x输入准备好”,多任务就不行了。另请参阅Vivado HLS 官方文档 ( UG902 ),了解有关稳定阵列部分的详细说明。

最后,inference_dataflow该函数第88行的pragma修改了外部寄存器接口,使得#pragma HLS interface ap_ctrl_chain port=return该函数可以用于同时处理多个帧。inference_dataflow如果没有这个 pragma,即使你实现了 ping-pong 缓冲区,主机端也只会尝试一个一个地执行它们,性能不会提高。

综合结果确认

可以在检查综合时检查任务并行化是否顺利进行。

下面是HLS综合结果报告,Latency -> Summary一栏列出了整个函数的延迟和执行间隔(Interval)。在这里,整体延迟仍然是所有任务处理时间的总和,但执行间隔的值conv2d_232_U0与第二个卷积层的执行周期数相匹配。该模块的吞吐量是第二个卷积层执行间隔的倒数。

8fdaeba94ded0530e407ad0def712bae.png

正如本文开头所解释的,conv2d_232_U0处理时间成为此任务并行化后电路中的瓶颈。任务并行化的速度提升率为947407 / 504898 = 1.88倍。

通过这种方式,我们能够确认 HLS 能够正确实现任务并行化。

总结

在本文中,我们通过提取任务并行性来加速处理。本来conv2占用了一半以上的执行时间,所以提速幅度不到2倍,如果设置为N,最大提速为N倍。

在下一篇文章中,我们将通过对卷积层应用数据并行化和循环并行化来解决每一层处理时间的不平衡。

关注我们

 OpenFPGA,与数万打工人共同成长

6eda7b804ad75112a2aa2462f13bce71.jpeg

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

ServletAPI详解(四)-HttpServletResponse

我们来看第三个方法,HttpServletResponse 在servlet运行原理中提到,servlet代码中的doXXX方法的目的就是根据请求计算响应,然后将响应数据设置到HttpServletResponse对象中,然后 Tomcat 就会把这个 HttpServletResponse 对象按照 HTTP 协议的格式, 转成一个字符串, 并通过 Soc…

Linux Shell 实现一键部署二进制Rabbitmq

rabbitmq 前言 RabbitMQ是实现了高级消息队列协议&#xff08;AMQP&#xff09;的开源消息代理软件&#xff08;亦称面向消息的中间件&#xff09;。RabbitMQ服务器是用Erlang语言编写的&#xff0c;而集群和故障转移是构建在开放电信平台框架上的。所有主要的编程语言均有与代…

MPC的560x系列的运行模式的介绍

一、模式简介 1、运行模式 一共11种模式&#xff0c;分别为RESET、DRUN、SAFE、TEST、RUN0、RUN1、RUN2、RUN3、HALT、STOP、STANDBY。其中RESET、DRUN、SAFE、TEST是系统工作模式&#xff0c;用户不用个特别关系&#xff0c;而后面几种是用于经常使用到的工作模式。 RESET&a…

Linux搭建docker

1. 查看系统的内核版本 [rootwide ~]# uname -r 3.10.0-1160.el7.x86_642. 将yum更新到最新版本 [rootwide ~]# yum upate -y Complete!3. 安装Docker所需的依赖包 [rootwide ~]# sudo yum install -y yum-utils device-mapper-persistent-data lvm2 Loaded plugins: fastes…

MyBatis多表查询+动态sql

文章目录MyBatis多表查询1. 多表一对一查询2. 多表一对多动态SQL1.\<if\>标签2.\<trim\>标签3. \<where\>标签4.\<set\>标签5. \<foreach\>标签MyBatis多表查询 在全局配置文件中中设置MyBatis执行日志 mybatis:configuration:log-impl: org.a…

hadoop使用MapReduce统计单词出现次数案例

前言 前面的文章已经展示了如何在windows上传文件到hdfs&#xff0c;上传后如何简单的做统计&#xff0c;本文展示一下。上传文件到HDFS链接 这里我们做一个案例&#xff0c;对一个上传到HDFS的文档中统计good出现的次数。 文件内容如下 这里我使用的是【上传文件到HDFS链接…

南方猛将加盟西方手机完全是臆测,他不会希望落得兔死狗烹的结局

早前南方某科技企业因为命名的问题闹得沸沸扬扬&#xff0c;于是一些业界人士就猜测该猛将会加盟西方手机&#xff0c;对于这种猜测可以嗤之以鼻&#xff0c;从西方手机以往的作风就可以看出来它向来缺乏容纳猛将的气量。一、没有猛将的西方手机迅速沉沦曾几何时&#xff0c;西…

linux服务器禁止ping命令,linux服务器禁ping如何解除

linux服务器禁止ping命令&#xff0c;linux服务器禁ping如何解除 我是艾西&#xff0c;在我们搭建网站或做某些程序时&#xff0c;不少人会问禁ping是什么意思&#xff0c;怎么操作的对于业务有哪些好处等&#xff0c;今天艾西一次给你们说清楚。 禁PING的意思是&#xff1a;不…

《花雕学AI》12:从ChatGPT的出现看人类与人工智能的互补关系与未来发展

马云说道&#xff0c;ChatGPT这一类技术已经对教育带来挑战&#xff0c;但是ChatGPT这一类技术只是AI时代的开始。 谷歌CEO桑德尔皮猜曾说&#xff1a;“人工智能是我们人类正在从事的最为深刻的研究方向之一&#xff0c;甚至要比火与电还更加深刻。” 360周鸿祎认为&#xf…

Java Web 实战 15 - 计算机网络之网络编程套接字

文章目录一 . 网络编程中的基本概念1.1 网络编程1.2 客户端(client) / 服务器(server)1.3 请求(request) / 响应(response)1.4 客户端和服务器之间的交互数据1.4.1 一问一答1.4.2 多问一答1.4.3 一问多答1.4.4 多问多答二 . socket 套接字2.1 UDP 的 Socket API2.1.1 引子2.1.2…

Ubuntu20.04 个人配置和i3美化

Ubuntu20.04 个人配置和i3美化 本文是基于个人习惯和审美&#xff0c;快速配置一个新ubuntu的步骤。脚本在资源里给出&#xff0c;但仍有部分配置文件需在脚本执行后手动修改,文中已用红色字体标出 更新apt源 备份原来的源更换阿里源 # 备份 sudo mv /etc/apt/sources.list…

基于Pytorch的可视化工具

深度学习网络通常具有很深的层次结构&#xff0c;而且层与层之间通常会有并联、串联等连接方式。当使用PyTorch建立一个深度学习网络并输出文本向读者展示网络的连接方式是非常低效的&#xff0c;所以需要有效的工具将建立的深度学习网络结构有层次化的展示&#xff0c;这就需要…

RK3399平台开发系列讲解(基础篇)Linux 传统间隔定时器

🚀返回专栏总目录 文章目录 一、设置间隔定时器 setitimer()二、查询定时器状态 getitimer()三、更简单的定时接口 alarm()四、传统定时器的应用4.1、为阻塞操作设置超时4.2、性能剖析五、传统定时器的局限性沉淀、分享、成长,让自己和他人都能有所收获!😄 📢本篇将详细…

【Vue】el与data的两种写法

data与el的2种写法 el有两种写法 new Vue时配置el属性。先创建Vue实例。随后再通过vm.$mount(‘root’)指定el的值。 data有2种写法 对象式: data:{}函数式: data(){ return {}} 如何选择&#xff1a;目前哪种写法都可以&#xff0c;以后学习到组件时&#xff0c;data必须使…

ERP软件的作用

ERP软件的运用是在企业管理系统的数据基础上实现的&#xff0c;它的应用涉及到企业的各个部门。ERP软件是在制造资源计划的基础上进一步发展而成的对企业供应链的管理软件。ERP是集采购、销售和库存、财务、生产管理和委托加工为一体的企业管理软件。它是集企业管理理念、业务流…

快速排序详解

一、定义 快速排序&#xff08;英语&#xff1a;Quicksort&#xff09;&#xff0c;又称分区交换排序&#xff08;英语&#xff1a;partition-exchange sort&#xff09;&#xff0c;简称「快排」&#xff0c;是一种被广泛运用的排序算法。 二、基本原理 快速排序是一个基于 分…

PostgreSQL下载、安装、Problem running post-install step的解决、连接PostgreSQL

我是参考《SQL基础教程》来安装的&#xff0c;关于书的介绍、配套视频、相关代码可以参照下面的链接&#xff1a; SQL基础教程&#xff08;第2版&#xff09; (ituring.com.cn) 一、下载 我直接打开书中的下载链接时&#xff0c;显示的是这个界面&#xff1a; You are not …

二维(三维)坐标系中旋转矩阵

求三维坐标系的旋转矩阵通常需要求分别沿3个坐标轴的二维坐标系下的旋转矩阵&#xff0c;二维坐标系下的旋转矩阵的推导过程通常以某一点逆时针旋转θ\thetaθ角度进行推理。以下将通过此例来详细讲解二维坐标系下的旋转矩阵推导过程&#xff0c;并进一步给出其他方式的旋转矩阵…

Surfshark下载到使用完整教程|2023最新

2023年3月16日更新 在正式介绍surfshark的教程( 教程直达学习地址: qptool.net/shark.html )之前&#xff0c;我们可以来看看最近surfshark的服务与产品退化到什么程度了。我曾经是Surshark两年的忠实用户&#xff0c;但是&#xff0c;现在&#xff0c;作为一个负责人的测评&a…

文件操作File类,OutputStream、InputStream、Reader、Writer的用法

文章目录File 类OutputStream、InputStreamInputStreamOutputStreamReader、WriterReaderWriter注意事项简单模拟实战File 类 Java标准库中提供的File类是对硬盘上的文件的抽象&#xff0c;每一个File对象代表了一个文件&#xff0c;因为文件在硬盘上存储&#xff0c;而直接操…