Skip to content

103yiran/how-to-optimize-gemm

 
 

Repository files navigation

how-to-optimize-gemm

RowMajor gemm optimization

编译和运行

  1. 准备 armv7/aarch64 linux 开发环境,树莓派/rk3399/aws arm server 都可以。
  2. clone 代码后,修改makefileOLDNEW。首次运行需要改成同一个代码版本,例如
OLD    := MMult_4x4_8
NEW   := MMult_4x4_8
  1. 默认情况下ARCH := native。直接编译运行即可
make run
  1. gflops 结果在对应.m 文件,用plot.py可绘制相关折线图。

fp32 gemm

此项目基于 blis-lab 文档和项目实现,与原作区别在于:

  1. 原作为列主序x86 SSE代码。考虑到移动端卷积优化一般使用arm架构芯片,本项目是基于arm64行主序gemm优化;
  2. 原作没有做 k 维拆解,也没有太细致的分块,离 CPU 极限差距不小。本项目目前最新的MMult_4x4_17.c最高可达 9.9gflops,相当于 CPU 峰值的 70%;
  3. 本项目没有处理边界问题,只考虑 MNK 均为 4 的倍数的情况;sub_kernel也只写了最简单的一种汇编。实用需要简单调整一下;
  4. 绘图方面扔掉了冗长的 octave(arm linux 配置一次环境太麻烦),改用 python plot

本系列优化中文教程在

  1. 知乎 GEMM 入门
  2. 知乎 GEMM caching (最后一节增加了理论支撑哦)
  3. ARMv7 4x4kernel 懒人优化小实践

int8 gemm

知乎 GEMM 入门 发布后,有不少同学问如何写一个 int8 gemm。本座写好了~~~

chgemm 是个可用的 int8 gemm 库。相对于本教程中的代码,区别在于:

  1. 处理了边界问题,不像教程里只考虑尺寸为 4 的倍数的情况;
  2. int8 最高达到了 18.6 gflops(相对 fp32 理论极限只有14.3,gemmlowp大约 12-14gflops);
  3. 基于对称量化原理,输入数值范围必须在 [-127, +127],不能出现 -128;

chgemm已合入ncnn INT8 卷积。

Releases

No releases published

Packages

No packages published

Languages

  • Fortran 50.4%
  • Assembly 26.5%
  • C 20.3%
  • C++ 1.4%
  • Makefile 0.8%
  • CMake 0.4%
  • Other 0.2%