防秒退提醒:如果你不懂 HLS 但是懂 FPGA,也可以读一下 Verilog 层面的优化手段。


高级综合(high-level synthesis,简称 HLS)能自动把 C/C++ 之类的高级语言转化成 Verilog/VHDL 之类的底层硬件描述语言(RTL),生成定制硬件在 FPGA 上跑实现加速。这使得不懂硬件的软件工程师也可以拥有玩转硬件的能力。HLS 的存在已有多年,它的优点,极短的开发和验证时间,使得它在学术界非常活跃;但是它的效率却一直被硬件工程师诟病:再怎么优化的 HLS 的硬件,还是没有手写的 Verilog 香啊!

香是香,可是 HLS 到底输哪了?到底值不值得用?

斯坦福大学教授 Juan J. Alonso 也好奇啊,然后他就挑了一类低运算难加速的应用,流体流动的模拟中的模版计算(Stencil Computations),对两者的性能进行比较。使用 Xilinx Vivado HLS 来设计自动解拉普拉斯方程的代码,然后与手写 RTL 比较,从而评估 HLS 无法直接做到的,但是手写 RTL 可以实现的一些优化。这样可以帮助硬件工程师更加了解 HLS,也可以在自己的工作中找到替代办法。今天我来分享一下第一个问题的答案,然后让读者有能力自己来回答第二个答案。

模版计算是什么?

模板计算上是一类处理多维数组的程序,通过使用其最近邻居的值来更新每个数组单元的值。这些相邻的单元由模板确定,模板是定义任何给定单元的邻域的固定模式。例如,在二维矩阵中,除了一个单元的四个正交邻居(即上,下,左和右邻居单元)外,五点模板还包括中心单元。另一方面,九点模具还包括四个对角线邻居。因此,模版计算的基本思想可以扩展到邻居的邻居。因为需要几个相邻的单元来计算单个单元值,并且操作数量不是很重要,所以模板计算的算术强度较低,因此对带宽的要求很高。另一方面,模版计算固有地是并行的,因为每个单元可以同时更新,并且只有直接邻居的访问才能导致较高的数据复用性。

本文选用了五点模板和 Jacobi 迭代方案 来求解拉普拉斯方程(

),这个算法和许多科学计算应用中使用的基于模板的运算类似。该算法在二维统一网格中实施,经过一系列迭代,通过平均每个内部单元的邻居,从输入一个生成输出矩阵。矩阵的边界单元保持不变,并且可以使用简单的副本进行更新。但是,通过将输入和输出矩阵初始化为相同的值,可以消除复制步骤,并且可以跳过边界单元。在每个时间步结束时交换输入和输出矩阵,然后循环继续进行,直到两个矩阵以适当的误差范数收敛。使用双精度浮点变量执行计算,并通过将均方差与用户设置的容差进行比较来确定收敛。

为了利用算法的局部性,文章以多个并行处理元素(processing elements,简称 PE),每个元素处理一个16行和256列的子矩阵。 PE 会在一个时间间隔中独立运行,但不会跨间隔独立运行,因为需要在每次迭代结束时执行收敛检查,然后才能进行下一个时间步,并且直到所有PE完成当前的处理才能执行。此外,每个子矩阵边缘的边界单元将必须从相邻的PE中获取其四个邻居之一,并且必须进行同步以确保检索更新后的值。此类单元称为“晕圈单元”(halo cells),它们的高效及时交换是高性能实施中的关键因素。为了在PE之间简单有效地交换光环单元,PE 垂直堆叠以将光晕限制在顶部和底部的PE行中。 PE 则被包装在顶层引擎模块中,该模块控制收敛检查的时间间隔。

每个 PE 都由管理输入和输出矩阵的 BRAM 控制器模块,计算每个单元的新值的平均模块以及计算 PE 累积误差的错误模块组成。PE 的基本操作包括在每个时间步中遍历两次输入矩阵。在第一遍中,从输入 BRAM 控制器中检索目标单元的四个邻居,并将其传递到平均模块。一旦计算值准备就绪,它将被从平均模块传递到输出 BRAM 控制器进行存储。在第二遍中,将输入矩阵中的原始值和存储在输出矩阵中的新计算的值传递到错误模块,然后将最终累积的错误转发到引擎模块以进行收敛性检查,基于所有PE计算的总错误。

最终设计的吞吐率为3个周期。(a)第一次通过需要两个周期,才能将四个邻居从输入BRAM控制器传递到平均模块。 (b)第二遍计算每个周期的误差。

用 Verilog 写能优化什么?

HDL 流水线设计通过遵循多个优化方向来实现高性能。首先,通过消除内存瓶颈来实现每个周期一个单元更新的理想PE吞吐量。 接下来,通过消除时间步和光环管理中的控制开销来减少运行时间。 最后,通过有效利用硬件资源,FPGA可以容纳更多的PE,以实现更高的计算能力。下面详细描述每种优化技术:

1. BRAM 分割

在第一遍中,平均模块需要访问四个邻居,而BRAM块仅支持两个端口,从而导致每个单元更新的模块吞吐量为两个周期。 但是,通过观察预定义的访问模式,我们注意到平均功能执行的四个访问仅需要两个具有相同奇偶校验的像元。 这样,通过将 PE 的 BRAM 存储器划分为两个块,并使用单元的奇偶校验位索引到 BRAM 块中,可以在一个周期内检索所有四个邻居,而不会发生冲突并且开销最小。 因此,通过有效地使存储器端口加倍,平均模块的吞吐量提高到每个周期一个单元更新。

2. 单次遍历

为了实现每个周期更新一个小区的 PE 吞吐量,必须融合两次遍历,以使 PE 每个时间间隔仅遍历其矩阵一次。因此,PE 必须在任何给定的周期内最多可以执行5次存储器读取,因为 RTL 设计的流水线性质必须允许平均和误差计算步骤作为不同流水线阶段的一部分同时发生。进一步的 BRAM 分区不能为错误计算所需的第五次访问提供有效的解决方案,因为它将引入复杂的访问管理以避免访问冲突。或者,通过观察当前单元格的右邻居将是下一个周期中的目标单元格来利用数据访问模式,一旦获得下一个单元格的错误,该值将与检索该值相同以计算下一个单元格的错误。通过缓冲每个单元的右邻居直到计算出其下一个单元的输出,我们完全不需要第五个内存访问。由于平均模块的延迟为29个周期,因此使用了一个基于寄存器的小FIFO,其中包含32个条目,以保留正确的邻居,直到相应的输出可用为止。

3. 无缝数据交换

通过利用 PE 执行的锁步性质,PE 可以像访问本地的光环一样访问其他光环,而不必在每次迭代的单独的先前步骤中交换光环。 之所以可行,是因为PE边界的单元仅使用四个可用BRAM端口中的三个,因此第四个端口可用于为相邻 PE 提供光晕。

4. 背对背迭代

假设矩阵尚未收敛,则可以通过背靠背运行时间步长来进一步减少总运行时间。 因此,与其等待一个时间步完成之后不等待收敛测试结果,不如立即进行下一个时间步,同时进行用于收敛检查的误差计算。 如果达到收敛,则中止时间步长,并返回输入矩阵,而不是输出矩阵。

5. 浮点除法优化

可以通过将昂贵的除以4.0运算和较便宜的0.25乘法相乘来减少硬件资源的数量。 但是,更大的资源节省将利用 FPGA 在位级别上处理数据并将浮点运算转换为整数运算的能力。 通过观察浮点除以4.0可以简单地将浮点数的尾数减少2,该浮点除法被十进制减法运算取代,从而每个PE释放10个DSP slice。

6. 浮点累加优化

利用每个 PE 的小数据量,通过将浮点累加器配置为最低资源使用率,我们将资源利用率降低了87%。 这不会影响结果的准确性,因为累加器仅用于收敛测试,在最坏的情况下,累加器会为每个子矩阵的4096个像元引入2^-53的舍入误差,总计 10^-6 的误差。

Verilog 的优化结果

表1列出了 HDL 实施中执行的以上六种优化技术,以及它们对性能的影响。

用 HLS 写能优化什么?

用 C 写 HLS 下,顶层函数包括一个主循环,该循环循环遍历时间间隔,并在每次迭代中对 PE 函数进行多次调用,然后使用 PE 函数返回值的运行总和检查收敛性。因为 PE 是作为功能实现的,所以子矩阵放置在顶层函数内,而不是每个 PE 内。除了指向光环所在的其他 PE 的子矩阵的指针之外,每个 PE 还会接收到输入和输出子矩阵的指针。

使用这种简单的实现,会出现两个问题。首先,不可能进行简单的指针交换来在两个子矩阵之间交替,因为不允许使用指针到指针,并且必须静态分配指针。其次,即使两个函数都不会更改数组的数据,也不允许两个函数访问同一阵列。当 PE 正在读取其输入子矩阵而另一个 PE 正在读取相同的子矩阵以访问其光环时,就是这种情况。为了解决此问题,创建了专用的光环阵列来复制光环单元,并将这些阵列传递给 PE 函数​​,而不是相邻的子矩阵。类似于双矩阵方法,每个 PE 具有两个光环数组,一个用于输入,另一个用于输出,并且引入了一个新函数来初始加载光晕。但是,此功能的性能成本可以忽略不计,因为它只能运行一次。尽管光晕数组方法会导致额外的内存使用,但这对于成功的代码生成是不可避免的。对于矩阵交换,PE 调用被复制并使用两种指针可能的参数组合进行硬编码,并且使用条件语句根据迭代的奇偶校验选择合适的调用。

通过解决这些问题,基线 HLS 实现成功生成了 RTL 代码,尽管显示出非常差的性能。这种性能下降的主要原因是 HLS 中没有浮点累加器,而是使用了浮点二进制加法器。使用加法器进行累加的问题在于加法器输入对其输出的自相关性:当前加法器的输出是下一个加法器的输入,因此,每个加法运算必须在开始下一个加法器之前完成。这意味着无法进行流水线操作,并且在加法器具有11个周期的延迟的情况下,处理一个子矩阵至少需要花费其大小的11倍(以时钟周期为单位)才能完成一个时间步长。为了提高性能,Xilinx 建议通过将值循环分配到几个加法器上来累加值,在任何加法器收到其下一个累加输入之前,至少要经过11个周期。每个加法器维护一个部分和,并且一旦子矩阵处理完成,也使用树加法器将这些和相加。

在适用的情况下,HLS 实现中采用了 HDL 版本中使用的优化技术。通过使用实用程序对BRAM 块进行分区以增加内存端口,并且还实现了通过缓冲来重用右邻居,但没有明确使用FIFO。取而代之的是,当 PE 遍历其单元时,右邻居被缓存在变量中,并由下一个单元在下一次迭代中使用。为了便于流水线化,HLS在内部实例化一个FIFO以保持该值,直到下一个单元的输出可用为止。

HDL 版本中使用的资源减少技术不适用于 HLS,因此无法复制。而且也没有将浮点除法转换为整数加法的操作,因为使用高级语言不容易访问位操作,并且违反了使用高级语言的目的。对于浮点累加器优化的方法也不适用,因为使用了加法器。实际上,为了克服加法器用作累加器的延迟,必须过度使用资源来实现部分和。

最后,无法通过连续执行时间间隔来进一步减少运行时间,因为循环流水线需要展开所有内部循环,这是不可行的。至于优化光环管理,设计根据 PE 的位置来对光环分别进行了优化:第一个 PE(使用底部光环),最后一个(使用顶部光环)或中间的 PE(同时使用两个光环) 。因此,光晕管理的延迟开销被最小化,但是光晕的双重缓冲和相关的内存使用无法得到改善。

Verilog VS. HLS - 案例结果比较

相较之手写 Verilog,HLS 能实现的优化十分有限:

对于 HLS 实施,浮点累加器的支持不足尤其成问题。加法器和部分和的使用引入了更高的延迟来计算部分和,并且由于包含部分和的数组,每个部分和的加法器以及用于最终求和的树加法器而增加了资源。 BRAM 的过度使用则是另一个问题,使用8个块进行部分求和用于存储,而 HLS 工具将每个PE实例化4个块以促进高效实现。

为了实现对右邻居的预取,该工具在内部使用了基于 BRAM 的 FIFO 来缓冲值。每个 PE 的 BRAM 使用量增加了六个或十个块,具体取决于 PE 的位置,无论它有一个还是两个光晕边缘。与不考虑 PE 位置而在 HDL 实现中使用的32个寄存器相比,这种对 BRAM 的过度使用表明该工具在复杂的控制逻辑方面的效率很低。虽然使用 HLS 可以改进数据流或控制流设计,但将两者组合在同一设计中对工具来说可能是挑战,并且可能导致性能下降,尤其是在涉及浮点运算时。

对资源的这种过度使用,使设计在 HLS 实现中仅容纳四个 PE,而在 HDL 版本中容纳八个 PE。尽管此较低的 PE 数量导致总体上减少了资源消耗,但 HLS 的实现因时钟变慢而受苦,这表明底层 RTL 描述不佳。另外,由于 HLS 版本无法对主循环进行流水线处理,因此迭代周期长,因此导致 PE 利用率低。结合更快的时钟,更大的 PE 数量和更高的 PE 利用率, HDL 实施方案在2.1W下每秒执行47000次迭代,而 HLS 版本仅每秒33000次迭代,而功耗仅低0.1W。因此,与 HLS 相比,HDL 版本每W的电池更新次数增加了一倍以上。两种实现的结果与 MATLAB 中开发的参考软件解决方案的结果在位上均相同。

抛开例子,HLS 到底输在了哪?

动态参数:HLS禁止动态分配指针,因为硬件设计通常具有多个存储空间,并且该工具必须知道函数打算访问哪个存储空间,以便可以相应地放置电线连接。动态传递函数参数的一种方法是通过静态定义所有可能的函数调用并对每个参数进行硬编码来引入间接层,然后使用条件语句动态选择正确的调用。

并行执行:为了确保正确执行,HLS 禁止访问同一数组的函数并行运行。由于不支持常量参数,因此它包括只读函数,因为无法对它们进行分类。必须拆分或复制数组,或者必须合并函数以启用并行执行。

内存过度分配:有两种方法可以将大型阵列合成为多个 BRAM 块链。首先是宽度扩展,它可以在多个 BRAM 块之间分配字位,并在每次使用内存的情况下同时激活多个块。第二个是深度扩展,它在每个块中存储完整的字,并使用多路复用器在每次存储访问中激活一个块,但会增加逻辑和延迟。为了实现高性能设计,HLS 似乎更喜欢宽度扩展,这会导致禁止使用 BRAM,尤其是在字非常宽且块未充分利用时。这样,将大型阵列拆分为较小的阵列以充分利用 BRAM 块可以大大减少内存使用量。

资源重用:序列化执行和重用逻辑的最有效方法是通过内联子功能提取公共逻辑。相反,关闭内联会重复资源并启用并行执行,尽管这种方法并不总是成功。确保并行执行的一种肯定但不太方便的方法是复制函数并以不同的方式重命名它们。当然,这种方法使代码难以维护,但是在某些情况下可能是不可避免的。

浮点累加器:由于没有浮点累加支持,实现累加的最有效方法是使用部分和和树加法器。

因此,可以得出结论,理想的方法是将 HLS 代码用于计算密集型部分与手工制作的用于逻辑控制和存储器管理的 HDL 实现相结合。但是,当内存管理和控制逻辑是应用程序实现过程中最复杂,最耗时的部分时(如本文所说),与纯 HDL 设计相比,混合方法可能不会增加太多价值。此外,在这种方法中,HDL 模块将被视为 HLS 设计中的黑匣子,从而阻碍了该工具重新使用 HDL 模块消耗的资源的努力。

无论哪种方式,HLS 都会带来自己的挑战,因为它将开发人员的注意力和精力从设计和测试转移到考虑该工具的意外行为,推测该工具为什么分配了这么多资源或产生了那么多延迟。因此,建议开发人员相应地设定他们的期望,并在项目规划中花费大量时间进行优化。

hls fifo_【FCCM2020】HLS 高手对比 Verilog 高手,到底输哪了?相关推荐

  1. hls fifo_【正点原子FPGA连载】第一章HLS简介--领航者ZYNQ之HLS 开发指南

    1)摘自[正点原子]领航者ZYNQ之HLS 开发指南 2)平台购买地址:https://item.taobao.com/item.htm?&id=606160108761 3)全套实验源码+手 ...

  2. 【HLS教程】HLS入门与精通

    总纲 HLS和FPGA实现是怎么一回事 HLS已有库说明 HLS语法讲解与实例 HLS自定义模板 HLS实现OpenCV函数 前言 主要还是工作中用到,HLS毕竟还是小众模版库,就目前来看,连Veri ...

  3. Xilinx Vitis HLS教程1--Vitis HLS概述[01/12]

    Xilinx Vitis HLS教程1--Vitis HLS概述[01/12] 前言 1 软件工程师的设计原则 1.1 简介 1.2 吞吐量和性能 1.3 架构问题 1.4 FPGA编程的3大范式 1 ...

  4. 到底怎么样的高手才是高手

    有人讲深藏不露者才是高手,这类高手平日一般都在深山老林中潜心修炼,与世无争,甚至一辈子都不愿意出手一次,圆寂之后才被后人发现,然后世世代代传为神话,相信这类高手一般不在CSDN. 有人讲适时出手者才是 ...

  5. 跆拳道高手与太极高手的较量

    跆拳道高手与太极高手的较量 视频    http://ike.126.com   文章来源:http://metababy.blog.hexun.com/7210662_d.html 找到一个精彩的视 ...

  6. Power BI和Tableau对比分析,到底要学哪个?

    Power BI和Tableau对比分析,到底要学哪个? 一.两个工具优缺点 Power BI Tableau 二.职业需求 前程无忧 智联招聘 三.总结 学习tableau还是power bi想必是 ...

  7. 《 Elasticsearch顶尖高手系列:高手进阶篇(最新第二版)》面前最新

    课程大纲 第1节结构化搜索_IT技术论坛案例背景介绍   9分钟   |  第2节结构化搜索_在案例中实战使用term filter来搜索数据   20分钟   |  第3节结构化搜索_filter执 ...

  8. hls.js播放hls直播源

    https://blog.csdn.net/qq_40816360/article/details/84074405 https://www.cnblogs.com/troublehuan/p/120 ...

  9. 百家号 python高手养成_python高手养成记04:python的所有数据类型,一篇足矣

    上一篇:python高手养成记03:面向对象是什么?网友:能3天掌握一门语言 题序: 在上一篇中,我们理解了面向对象的思想,只需要大致理解即可,因为后面我们会专门做这一块的培训.在本篇中,小编来讲解p ...

最新文章

  1. linux(ubuntu) 查看系统设备信息 命令
  2. 内核知识第九讲,32位下的分页管理,36位下的分页管理.以及64位下的分页管理
  3. mysql安装后配置
  4. geometry-api-java 学习笔记(二)点 Point
  5. RabbitMQ笔记-使用rabbitmq-c实现Fair dispatch(公平分发)
  6. 机会是留给有准备的人
  7. sob攻略超详细攻略_【五一四天旅游攻略】凤凰古城和长沙旅游攻略,超详细!可以参考...
  8. WebStorm和VSCode配置
  9. Python: 常用的软件包
  10. 计算机学院品牌活动总结,计算机学院研究生会工作总结
  11. 【微软内推】微软2023届校园招聘开始啦
  12. ElasticSearch 基础(七)之分析器
  13. 静态路由基础,扩展配置 超详细滴
  14. Some Enforcer rules have failed. Look above for specific messages explaining why the rule failed.
  15. 软考 - 10 智能家居管理系统
  16. 分享:Vue.js新手入门指南-0518-v1.0张雅慧(续)
  17. 10款不可多得的精美png图标
  18. MBIST Algorithm - Testing algorithm
  19. php系统发布_用PHP制作新闻发布系统
  20. 数据科学课程笔记1 --- 导论

热门文章

  1. webstorm的使用技巧——1
  2. PPT | Docker定义存储-让应用无痛运行
  3. 学习python的一些心得和经验
  4. FP与IP作为两种编程范型的解决问题思路及其适用领域分析
  5. Solaris 10网络服务
  6. 函数计算新功能-----支持C#函数
  7. 用vue-scroller做上拉刷新,下拉加载的模板(简单明了,通用)
  8. 图片裁剪的js有哪些(整理)
  9. MyBatis SQL语句操作Mysql
  10. 用大数据分析顾客会掏钱买你哪件商品