vitis使用的一点心得

1 在一个for循环中实现两个不相干的逻辑,一般会优化成串行逻辑,这样需要多一倍的时钟,即使是告诉编译器两个逻辑共享参数无关、使用dataflow都不行,这个时候可以看看是否在循环中通过if else两个分支来处理,如果两个不相干的逻辑刚好可以错开执行,if else是不错的选择,编译器很容易会改成并行逻辑

2 dependence的intra表示的是for循环不同循环(i值不同)间的参数关系,不是不同for循环间的,dependence是有作用的,如果加上denpendce仍然无效,需要考虑是不是其它因素,比如:raw连线限制、执行时延必须要多个时钟(可以用latency限制,但是latency会导致时钟频率上不去)

3 array_partition很有用,在有时候需要多个时钟的情况下,很多场景都是因为访问raw的瓶颈导致的,这个时候如果ram不大,可以用array_partition展开。当然也可以通过扩大位宽解决

4 在调周期时延时,对综合周期时好时坏,letency是有效果的,但是如果差太多就不行

5 目前看来循环和函数间并行只有dataflow有作用。pipeline是循环内部流水打拍,主要用于需要多个时钟执行的情况,pipeline使用的前提是多次循环间没有相互依赖,比如:正常情况只需要一个临时变量来临时保存数据,但是想用pipeline需要定义成数组,并且临时变量要存储到对应位置,这样pipeline才能有效。dataflow的核心还是需要让编译器能预测不同循环间执行的关系,如果不能明确循环间的执行关系,dataflow就没办法了。

6 dataflow目前发现两种玩法:

1) 循环间

int  a[100],b[100];

loop1:

for( int i=0;i<100;i++)

{

        a[i] = i;

}

loop2:

for(int i=0;i<100;i++)

{

        b[i]=a[i];

}

上述代码dataflow就有效果,因为在loop1中a数组赋值是明确的,每个时钟都会有一个元素被赋值;这样在loop2中就可以预测a数组的元素什么时候有效,就可以给b数组赋值了;反之如果a数组元素赋值不可预测,loop2就不清楚什么时候可以启动,也就不能dataflow了。所以dataflow的核心是后面循环依赖的数据生成可预测。

需要特别注意:在消费者的循环中,必须显示的有i的存在,只有这样编译器才能明确判断生产者和消费者的关系,从而确定何时启动消费者

如果loop2需要多个时钟执行,如下逻辑

loop2:

for(int i=0;i<100;i++)

{

        b[i]=a[i];

        b[i] = b[i]*a[i];

}

这个时候可以用pipeline,因为每个循环只依赖明确的元素,迭代之间不相互影响。

2)stream做为函数间参数,并且只有stream做为参数

void foo1(stream<ap_uint<64>& output,int a,...)

{

        /// 生产者

}

void foo2(stream<ap_uint<64>& input,int A,...)

{

        ///消费者

}

上述函数可以用dataflow,会产生两个流水线,并且每个流水线相互独立、互补干扰,而且只依赖stream有没有数据。

7 if else时钟周期的平衡

在循环或者top层如果有if else循环,那么在分析的时候会按照多的来判断需要的时钟周期数,所以在设计的时候,需要考虑频繁使用的分支周期短,不要影响主路径。如果多个if else if else也是一样

8 dataflow无效的原因

1) dataflow只能对函数或循环使用,如果在if分支这种使用肯定无效

2) 如果接线紧张也会导致时序无效

9 代码优化导致增加时钟周期

比如代码如下:

a=b;

b=c;

c=d;

上述代码是希望顺序执行,但是编译器有可能会优化成

c=d;

b=c;

a=b;

它始终认为应当先写后读,上述代码a获取到值需要3个时钟,会远远超过预期。一般这种情况可以dependence来指定读写的关系,但是测试下来貌似没有作用,而且这种情况往往很难判断是时序紧张导致还是编译器优化了顺序,判断这个问题可以通过if else分支来测试,如果强行把某部分代码放入if else 分支中,比如:

if(xxx)

        a=b;

else if(xxx)

        b=c;

else

        c=d;

这样就编译就没办法优化了,如果这种情况能达到综合目标,说明是因为编译器优化了,不是时序问题

9 在测试中发现有些功能使用无效果,比如 array_reshope 和array_partition,一个是调整位宽,一个是ram分块,尝试下来都不好用,有时候甚至适得其反。

比如:原来设想用array_partition+cyscel,将数据重新组合成块,保证在使用某一个元素的时候一拍搞定,但是效果非常差。然后想用array_reshope调整位宽,发现也没效果,最后干脆重新定义了位宽,效果非常好。这个事情说明有些时候最简单的也是最有效的,直接代码实现比一堆宏更有效。

目前用的比较多的有pipeline、dataflow,unroll,inline其它的感觉都不是很理想,后面用到再总结吧

10 移位的问题

今天调试代码优化时序,遇到一个不可思议的事情,基本代码如下:

for( int i=0;i<10;i++}

{

#pragma HLS unroll

    if( i> idx)

        a[i] = a[i+1];

}

设想代码应该一个时钟可以搞定,但是要10个时钟,百思不得其解,怀疑了几个点:

1) unroll不支持if判断场景,但是分析下来好像也没什么问题,后来人工把i各个取值强行展开,仍然是10个时钟;然后把if去掉,仍然是10个时钟,通过两步测试,确定不是unroll无法展开if的问题,unroll展开if完全没问题

2) a是ram,一次读写要一拍,这个问题不好验证,反正array_partition complete也使用了,包括位宽扩大也用了,仍然没效果

3 代码优化,由于a[i]=a[i+1]会不会是由于读写先后顺序导致的,改成两个循环

for( int i=0;i<10;i++}

{

#pragma HLS unroll

    if( i> idx)

        b[i] = a[i+1];

}

for( int i=0;i<10;i++}

{

#pragma HLS unroll

    if( i> idx)

        a[i] = b[i];

}

仍然不行

结果最后发现是由于这个函数前面有个依赖,需要几个时钟,加起来刚好10个时钟,很郁闷。这个事情分析下来发现还是经验不够,对这个块代码不够自信,需要多总结。现在看来上面3个场景都没有问题。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Vitis AI 是 Xilinx 公司推出的面向边缘AI应用的综合开发环境,可以支持Keras,TensorFlow和Caffe等一系列深度学习框架的模型优化和部署。以下是Vitis AI的使用方法: 1. 下载并安装Vitis AI Vitis AI可在Xilinx公司简介页下载,也可在官网上下载。下载后按照安装说明进行安装。 2. 创建项目 创建Vitis AI项目需要 Vitis AI 以及支持的硬件平台。平台支持 Ultra96、ZCU104、Alveo U250 等等,开发板需要使用 PYNQ 作为操作系统。在PYNQ环境下,可以打开缺省安装好的终端,进入Vitis AI目录下,使用以下命令创建项目. ``` source /opt/vitis_ai/setup.sh ``` ``` vitis_ai_compiler ``` 3. 选定深度学习框架 选定需要使用的框架,Vitis AI支持的框架包括TensorFlow、Caffe、Keras和ONNX等。对于Pynq而言,需要 手动编译Caffe或TensorFlow等框架,也可以选择已经编译好的模型。 4. 选择模型 用户需要将模型转化为量化模型或是进行裁剪时,需调用Xilinx提供的quantizer和pruner工具一步步进行操作。如果需要直接使用一个已经训练好的模型,可以选择 Vitis AI 中预训练好的模型。 5. 优化模型 Vitis AI在使用量化和裁剪等功能后,可以使用针对AI加速的DPU IP作为部署目标。使用DPU IP的目的是,DPU IP是专为AI推理加速而设计的硬件单元,并且在 Vitis AI 中已经对完整的神经网络架构做了适配的模型库。 6. 部署和测试 完成模型优化和调试后,使用Vitis AI提供的shell脚本及SDK对模型进行编译和测试。编译后部署到FPGA板子上即可,执行一段测试脚本即可运行并评估程 度。 以上便是Vitis AI的简略使用方法。由于平台及硬件不同,详细的操作流程会略有不同。用户应该根据输入输出数据及框架选择手册中对应的执行方式。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值