首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

使用FPGA优化视频水印操作的OpenCL应用-2

使用FPGA优化视频水印操作的OpenCL应用-2

FPGA水印算法的首个实现方案如图4所示。这是一个功能正确的应用实现方案,但没有进行任何性能优化或为充分利用FPGA架构的功能进行考虑。因此该代码在SDAccel中编译完成后,在Alpha Data卡上运行得到的最大吞吐量仅为0.5fps。  从图4的代码中可以看到,这种水印算法不是一种高计算强度的设计。大多数时间花在访问内存,读取和写入视频帧上。因此我们在优化实例设计时,把重点放在优化内存带宽上。
  图4 - 水印内核的初始实现方案
  使用矢量化优化内存访问
  与其他软件可编程架构相比,FPGA架构的优势之一在于灵活性强,能配置连接内存的总线。SDAccel能根据具体的应用内核创建用于连接内存的定制化数据路径和架构。通过修改代码,一次可以处理多个像素,从而能够从内核中调用更高的内存带宽。这个过程称之为矢量化。
  矢量化的程度是否合适,取决于具体应用和所使用的FPGA加速器卡。以Alpha Data卡为例,设备全局内存接口宽度为512位,这与SDAccel为内核提供的最大AXI互联宽度一致。鉴于最大带宽为512位,该应用调整为每次处理20个像素(24位/像素×20像素=504位)。SDAccel完全支持矢量数据类型。因此就本应用而言,代码的矢量化非常简单,就是把所有阵列的数据类型修改为char20(如图5所示),这样吞吐量就能达到12fps。
  图5 - 矢量化后的内核代码
  使用突发模式优化内存访问
  虽然矢量化能显著改善应用性能,但仍不足以实现30fps的吞吐量目标。该应用仍然受内存局限,因为内核每次只能向内存传输20个像素。为减轻内存限制对应用造成的影响,我们不得不修改内核代码,以生成到内存的突发读取/写入操作,从而实现大于20个像素的数据集。修改后的内核代码见图6。
  图6 - 针对突发数据传输优化的内核代码
  代码内核首先修改的是在内核中定义片上存储,以便每次存储像素块。片上内存用内核代码中声明的阵列来定义。为启动到内存的突发事务处理,该代码实例化memcpy命令,以将数据块从DDR移到内核内的BRAM存储系统中。根据片上内存资源的大小和待处理数据的量,一个视频帧可分割成20个1920×54像素块(如图7所示)。
  图7 - 把视频帧分区成数据块
  当memcry命令把数据块放置到内核阵列中,该算法就会在数据块上执行水印算法,然后把结果放回内核阵列。数据块处理的结果随后使用memcry命令传送回DDR内存。反复执行这个操作20次,直至给定帧中所有的数据块处理完毕。通过修改内核代码,系统性能达到了38fps,超过了既定的30fps目标。
  应用前景广泛
  使用SDAccel开发本文介绍的这类应用时所进行的必要优化属于软件优化。因此这些优化工作与从其他处理架构中(如GPU)获取性能所开展的优化类似。使用SDAccel后,让PCIe链路工作、驱动程序、IP布局和互联等细节都不是问题,使我们就像设计人员一样只需集中精力开发目标应用。
  我们在水印应用中所做的优化适用于使用SDAccel编译过的所有应用。事实上视频水印应用就是一个很棒的技巧讲解案例,详细介绍了赛灵思SDAccel中推出的优化方法。
返回列表