跳转到主要内容

ZynqNet解析(一)概览

judy 提交于

背景:ZynqNet能在xilinx的FPGA上实现deep compression。

目的:读懂zynqNet的代码和论文。

<strong>一、网络所需的运算与存储</strong>

1.1 运算操作:
<li>macc:multiply-accumulation,</li>
<li>comp:comparison</li>
<li>add: addition/substraction</li>
<li>div:  division</li>
<li>exp:  expontential</li>

1.2 Memory requirements:
<li>activation:  size of output feature maps</li>
<li>param:  number of weight parameters</li>

1.3 需求分析:
<li>网络为1×1和3×3的卷积,所以将近530 million次MACC操作。</li>
<li>ReLU操作耗费将近3 million次comp操作。</li>
<li>均值池化需要66000 次加法和一次除法,</li>
<li>最终的softmax需要执行1024次exponentiation,add和div。</li>
<li>exponentiation与division很少,所以softmax层被ARM处理器执行。</li>

1.4 FPGA based accelerator需要执行:
<li>conv layer:</li>
       kernel 1×1,padding 0
       kernel 3×3,padding 1
       stride 1 or stride 2
<li>ReLU nonlineralrties</li>
<li>concatenation</li>
<li>global average pooling</li>

<strong>二、网络结构</strong>

针对网络结构进行了三种优化:
<li>efficiency-related optimization (report 3.4.1)</li>
<li>FPGA-related optimization(report 3.4.2)</li>
<li>accuracy-related optimization(report 3.4.3)</li>
<li> FPGA-realted optimization(3.4.2)</li>

<li>2的次方数的维度:能减少14%的参数和9%的MACC操作。</li>
<li>全卷积网络:只包含卷积和非线性的网络。我们将最大值池化改为步长为2的subsequent conv.</li>
<li>Layer splitting:因为on-chip memory的不足,xc-7z045只有2180kB个Block RAM memory,只能存储560 000 个32bit 浮点参数。conv10被分为conv10/split1与conv10/split2</li>
<center><img src="http://xilinx.eetrend.com/files/2019-01/%E5%8D%9A%E5%AE%A2/100017438-58…; alt=""></center>

循环嵌套:
循环嵌套顺序layer——height——width——input channel——output channel——kernel elements
<center><img src="http://xilinx.eetrend.com/files/2019-01/%E5%8D%9A%E5%AE%A2/100017438-58…; alt=""></center>
<center><img src="http://xilinx.eetrend.com/files/2019-01/%E5%8D%9A%E5%AE%A2/100017438-58…; alt=""></center>
<center><img src="http://xilinx.eetrend.com/files/2019-01/%E5%8D%9A%E5%AE%A2/100017438-58…; alt=""></center>

<strong>三、编译优化</strong>

并行处理(4.2.3)
并行策略,将所有3×3的循环展开(fullly unroll),unroll the output channels co by 参数N(PE)

数据复用(4.2.4)

四种on-chip cache
<li>ICache(Image cache):line buffer,为input feature map准备的。</li>
<li>OCache(Output cache)</li>
<li>GPoolCache(Global pooling cache)</li>
<li>WCache(weights cache):最大的cache,需要当前layer的ci×co个filter</li>

每一个输入像素都被加载一次,输出像素也被加载一次,权重也被取一次。相比于main memory access,这种算法的数据复用较为理想。

Coding Style(4.4.2)

object-orinted

最初整体的进行编程与调试,HLS报错,作者并不知道错误在哪里。因此作者使用object-orinted的方法。

<li>hardware block modules被作为class instances,包括MemoryController, ImageCache, WeightsCache, OutputCache, ProcessingElements</li>
<li>数组与变量被封装为private class members</li>
<li>数据搬运被实现在高级别的函数中。</li>
<li>控制依然在top-level的嵌套的函数中(layer,height,width,inputchannels)和class ProcessingElement(output channel与kernel y与x)</li>

这种编码模式在综合之中就更容易查找问题。但是因为编译等等的问题,作者依然不能调通。

  Block-structured(ZynqNet采用的)

这种方法运用namespace来确定相应的代码,部分被运用下面的方法:

<li>namespace to structure code into modules</li>
<li>数组与变量被封装于namespace-scopes中</li>
<li>数据搬运通过high-level namespace-scoped 函数来进行</li>
<li>控制依然通过top-level的嵌套的函数中(layer,height,width,inputchannels)和namespace ProcessingElement(output channel与kernel y与x)</li>

最终的代码优点:
<li>直接,接近硬件描述</li>
<li>易于阅读,更改和调试</li>
<li>易于运用优化指令</li>

Compiler Directives(4.4.3)

具体的硬件实现需要对相应的c/c++代码进行编译指令。

包括了Interfaces, function-level interface protocols, port-level interface protocols, AXI4 interfaces, AXI4 Depth Settings。

Data and control flow

涉及每个指令的优化的意义与硬件相关讲解。

Loop Unroll, Dependencies,Pipeline,resource specification and pipelining of arithmetic operation. Function inlining, Function instantiation , Dataflow

<strong>四、实现方法(4.5.1)</strong>

FPGA side
通过文档UG871,我们可以将相应的代码生成为相应IP core,然后根据下面搭建系统。(通过这个我们看出HLS最高级别的函数为FPGA top)。然后VHLS会将相应的系统生成VHDL或者Verilog wrapper。然后就可对设计进行synthesis,之后RTL会生成相应的比特流,.bit文件
<center><img src="http://xilinx.eetrend.com/files/2019-01/%E5%8D%9A%E5%AE%A2/100017438-58…; alt=""></center>

CPU side
  Xilinx Software Development Kit
Vivado Design Suite会输出一个 .hdf文件(hardware design file),后续会被SDK打开,可以创建一个裸的不需要操作系统的应用。它包括所有的工具来创建一个完整的新的Linux环境下的First Stage Boot Loader(FSBL)

Memory-Mapped Input and Output

Vivado Design Suite会输出基于c的AXI4-Lite的驱动:

<li>开始与停止top level FPGA entity</li>
<li>check statue of acceleator(idle 、ready 、done)</li>
<li>设置与获得所有AXI-Lite接口的参数</li>

  ZynqNet驱动:
<li>当前的First Stage Boot Loader(FSBL)在zynqbox configuration中对programmable logic为FCLK_CLK0的时钟源100MHz,所以ZynqNet的FPGA accelerator只是运行了200MHz的一半。</li>
<li>在启动驱动之前,S_AXI HP0应被设置为32 bit bus width。</li>
<li>对于ZynqNet的FPGA加速器需要加载zynqnet_200MHz.bit.</li>
---------------------
作者:邢翔瑞
来源:CSDN
原文: https://blog.csdn.net/weixin_36474809/article/details/82621009