小白会长 · 2021年11月22日

ARMv7 4x4kernel 懒人优化小实践

... 下面都是现学的,现学现卖...

硬件环境

树莓派 3B,32bit 操作系统,A53 芯片。 理论峰值 10.2 gflops。

代码 Base

本来应该从头写的,可是懒。直接取了
https://github.com/MegEngine/MegEngine/blob/master/dnn/src/armv7/matrix_mul/fp32/strategy_4x12.cpp
拷贝到 armv7_gemm 分支
https://github.com/tpoisonooo/how-to-optimize-gemm/blob/armv7-gemm/src/HowToOptimizeGemm/MMult_4x4_19.c
就在这个基础上改吧...大佬已经介绍过原文链接里面的技巧,不再赘述。

先简单测一下,在小破板子上目前 2.86gflops

图片.png

2.8gflops

load 优化

先看结果...

图片.png

主要干了三件事:

  1. 换成了更长的 pld 指令,把多个 pld #128 合并成 pld #512
    节约指令是一方面,另一方面 A53 存储器很弱,pld 需要更多时间
  2. 扔掉 ldq,改 ldd
  3. 指令混排,掩盖开销

理由是:A53 上 ldq 需要 2 cycle,且无法和 vmla.f32 双发射。这点可白嫖 ncnn dev 文档
https://github.com/Tencent/ncnn/blob/master/docs/developer-guide/arm-a53-a55-dual-issue.md
里面提到:

图片.png

ncnn dev doc

ldx + ins 目前没想法,毕竟 32bit 小破系统,总不能一换四...

更换 vldr

这是从 Tengine 白嫖的啊

原来的实现中有些 update pointer

图片.png

vld1.f32 更新指针

并没有和 fmla 一起 dual issue。

改成了先 vldr 带偏移加载,最后用add指令更新指针;顺带简单调整一下 ping-pong

图片.png

目前 3.9 gflops,还没有用提前 pack 和 nc4hw4,先水到这儿...

如果是 A7,可以白嫖 megengine 啊
https://github.com/MegEngine/MegEngine/blob/master/dnn/src/armv7/matrix_mul/fp32/strategy_4x12.cpp

4x12不香么,看我现在多懒...

图片.png

END

原文链接:知乎
作者: 白牛

推荐阅读

更多嵌入式AI技术相关内容请关注嵌入式AI专栏。
推荐阅读
关注数
16759
内容数
1233
嵌入式端AI,包括AI算法在推理框架Tengine,MNN,NCNN,PaddlePaddle及相关芯片上的实现。欢迎加入微信交流群,微信号:aijishu20(备注:嵌入式)
目录
极术微信服务号
关注极术微信号
实时接收点赞提醒和评论通知
安谋科技学堂公众号
关注安谋科技学堂
实时获取安谋科技及 Arm 教学资源
安谋科技招聘公众号
关注安谋科技招聘
实时获取安谋科技中国职位信息