查看原文
其他

华为端引擎Bolt GPU性能优化:让上帝帮忙掷骰子

lfan NeuralTalk 2022-11-28

概述

移动端GPU在深度学习网络前向推理中占据着重要的地位,硬件本身具备高性能低功耗,适应大规模密集型计算等优势。普及已久的OpenCL与新兴的Vulkan也为其提供了完整的并行编程解决方案。不断推进深度学习前向推理的GPU支持与优化是业界的共同目标。

Bolt深度学习轻量级推理库的MALI GPU支持始于2019年12月初,至今已覆盖绝大部分视觉网络,且持续向语音语义领域迈进Bolt GPU在常见视觉网络性能测试中超越同类开源库15%~50%,具有明显的优势。


图1 Kirin 990 GPU性能对比测试

图2 Kirin 810 GPU性能对比测试


  • 恰逢一年之际,笔者借此分享一些移动端GPU优化的心得。

  • Github链接:https://github.com/huawei-noah/bolt

  • 用户交流QQ群:833345709

何为上帝掷骰子?

在如今这个内卷激烈的时代,沉淀已久的CPU与性能强大的服务器端GPU以汇编为道,性能评价指标是绝对的带宽峰值或者Gflops峰值。另一方面性能与GPU相当的DSP,甚至超越GPU的各类APU也逐步加入竞争行列。反观移动端GPU,底层架构与指令集的开源仍然是个未知数优化人员遵从的无非是合并内存访问、提高数据复用率、减少线程分支等GPU通用优化原则,在尽可能提高单线程数据复用性的情况下,减少寄存器等资源的占用成本,保证较高的并行度

然而这种方式的优化似乎没有尽头,单就一个直接卷积,我们在移动端GPU便可以看到数十种实现方案,目的都是为了适应不同规模的数据或不同型号的GPU。优化人员的工作变为不断为新的网络或硬件添加我们自以为最优的计算配置,反复的尝试与测试费心费力,而无限扩张的Kernel数量带来额外的管理负担。

这一过程无异于上帝掷色子,每当写好一个新的配置,性能测试就好像是等着上帝来开奖,你甚至都不知道自己到底是否中奖,运气好时相比之前的实现有所提升,运气差时只能从头再来。

如何让上帝来帮忙?

Bolt GPU优化同样面临着上述问题,为了中断这种无休止的尝试,并在短期内开发出一套业界领先的计算方案,我们希望上帝能给予一点帮助,为此需要从制造骰子转变为制造骰子生成器。

我们对计算密集型算子的Kernel实现进行了抽象,通过宏函数定义出各个抽象单元的基本实现,再基于不同的宏参数快速生成不同计算配置的Kernel,最后配合实时算法选择调优,让上帝帮忙掷出当前性能最优的配置,下面以直接卷积为例进一步说明。

图3 Bolt GPU直接卷积数据排列

首先Input与output均采用了C4的数据格式,即将Channel通道中的每4个点聚集为一个4维的向量,配合OpenCL的vload4循环读写。其次每个线程计算一个竖条,如图3所示,通过宏参数IN定义竖条的长度,即一个线程读入的Input个数。条状数据块可减少单线程寄存器占用量,方形数据虽然具备更高的数据复用率,但用寄存器的消耗是条状的两倍以上。竖条的另一个好处是IN的改变不影响相邻线程数据访问间隔,其值始终都为1。

因为Input与output均采用C4数据格式,filter的读取自然变成input channel 4 output channel 4共计16个点,将filter ic4与oc4对应的16个点聚集,配合OpenCL的vload16循环读取。如图3所示,Filter w/h size的变化不会影响该读取模式,只是循环次数不同。C4数据格式将直接卷积实现的读写模式规律化,为下面的Kernel实现抽象提供了可能性。

图4 Bolt GPU直接卷积生成

如图4所示,Kernel实现被抽象为数个模块,每个模块由宏函数实现,定义需要的宏参数即可编译出相应计算配置的Kernel,图5为bolt直接卷积Kernel性能测试情况。

图5 Bolt GPU直接卷积性能测试

总结

GPU的性能崛起推动了整个AI时代的兴起与发展,Bolt GPU的支持与优化既是我们项目的重点,也希望能给业界带来新的动力。除去持续性的性能优化,易用轻量优化与语音语义支持会是下一步的重要方向。移动端GPU优化仍然面临着很多问题与挑战,欢迎各位有兴趣的童鞋加入Bolt(后台回复:华为诺亚,诺亚)。

点击【阅读原文】,看往期文章

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存