... 下面都是现学的,现学现卖...
硬件环境
树莓派 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
2.8gflops
load 优化
先看结果...
主要干了三件事:
- 换成了更长的 pld 指令,把多个 pld #128 合并成 pld #512
节约指令是一方面,另一方面 A53 存储器很弱,pld 需要更多时间 - 扔掉 ldq,改 ldd
- 指令混排,掩盖开销
理由是:A53 上 ldq 需要 2 cycle,且无法和 vmla.f32 双发射。这点可白嫖 ncnn dev 文档
https://github.com/Tencent/ncnn/blob/master/docs/developer-guide/arm-a53-a55-dual-issue.md
里面提到:
ncnn dev doc
ldx + ins 目前没想法,毕竟 32bit 小破系统,总不能一换四...
更换 vldr
这是从 Tengine 白嫖的啊
原来的实现中有些 update pointer
vld1.f32 更新指针
并没有和 fmla 一起 dual issue。
改成了先 vldr 带偏移加载,最后用add
指令更新指针;顺带简单调整一下 ping-pong
目前 3.9 gflops,还没有用提前 pack 和 nc4hw4,先水到这儿...
如果是 A7,可以白嫖 megengine 啊
https://github.com/MegEngine/MegEngine/blob/master/dnn/src/armv7/matrix_mul/fp32/strategy_4x12.cpp
4x12不香么,看我现在多懒...
懒
END
原文链接:知乎
作者: 白牛
推荐阅读
更多嵌入式AI技术相关内容请关注嵌入式AI专栏。