本帖最后由 zhanzr21 于 2017-2-6 19:13 编辑
现在正在做一个算法相关的产品, 所以对嵌入式算法库阿,优化这里做了一点小研究, 主要是ARM内核的CMSIS DSP库.
CMSIS DSP这个库很多人的电脑上都有很多份的Copy, 因为什么工具阿, 软件包都会包含这个在内, 比如安装了Keil MDK, IAR, Tasking, XMC Lib, USB Lib之类都会附带一个. 版本有很多种, 因为一直在更新. 估计不使用这个的人都没有留意.
这里以Keil附带的CMSIS DSP库为例子, 位置在这里:
当然你使用器件DFP自带的版本也可以, ST测试过可能兼容性更好.
这个DSP Lib包含如下几类内容:
- 基本数学函数(绝对值,多精度乘除)
- 常用表格(比如FFT中要用的蝶形因子表格,正弦表格,很多时候查表比计算快很多)
- 复数运算函数
- PID相关函数
- 滤波器函数(卷积,FIR,LMS等等)
- 矩阵算术函数
- 统计学函数(RMS,VAR,STD,平均值,最大最小)
- 变换函数(FFT,反向FFT, 离散余弦变换等等)
需要指出的是, 这里面许多算法跟C Lib, C++ Lib中的很多功能有重叠之处, 比如开方, 幂函数, 三角函数, 但是这个库里面的函数都是为ARM内核深度优化的, 如果需要性能, 就应该尽量使用这个库里面的函数.
下面以一个矩阵相乘的例子简单看看如何使用这个库:
设定好路径后, 包含这个文件就可以了:
#include "arm_math.h"
对, 只用包含这个文件,
再添加这个lib:
选l还是lf版本的看你的CPU是否带有FPU.
开始使用:
定义两个矩阵的数据,当然也可以自动生成这里求简便:
- /* ----------------------------------------------------------------------
- ** First Matrix (DATA_LINE_N * DATA_COL_N)
- ** ------------------------------------------------------------------- */
- const float32_t firstMat_f32[DATA_LINE_N * DATA_COL_N] =
- {
- 42, 37, 81, 28,
- 83, 72, 36, 38,
- 32, 51, 63, 64,
- 97, 82, 95, 90,
- 66, 51, 54, 42,
- 67, 56, 45, 57,
- 67, 69, 35, 52,
- 29, 81, 58, 47,
- 38, 76, 100, 29,
- 33, 47, 29, 50,
- 34, 41, 61, 46,
- 52, 50, 48, 36,
- 47, 55, 44, 40,
- 100, 94, 84, 37,
- 32, 71, 47, 77,
- 31, 50, 49, 35,
- 63, 67, 40, 31,
- 29, 68, 61, 38,
- 31, 28, 28, 76,
- 55, 33, 29, 39
- };
- /* ----------------------------------------------------------------------
- * Second Matrix (DATA_COL_N * 1)
- * ------------------------------------------------------------------- */
- const float32_t secondMat_f32[DATA_COL_N] =
- {
- 1,
- 1,
- 1,
- 1
- };
注意这个函数库中的数据类型:float32_t就相当于通常说的单精度浮点数
q31_t 相当於32位有符号整数
q15_t ..... 16....
q7_t ..... 8...
定义结果buffer:
- /* ----------------------------------------------------------------------
- ** f32 Output buffer
- ** ------------------------------------------------------------------- */
- static float32_t testOutput[DATA_LINE_N];
因为是20*4的矩阵乘以 4x1的矩阵,那么结果应该是20*1的矩阵
初始化矩阵:
- arm_matrix_instance_f32 srcA = {DATA_LINE_N, DATA_COL_N, (float32_t *)firstMat_f32};
- arm_matrix_instance_f32 srcB = {DATA_COL_N, 1, (float32_t *)secondMat_f32};
- arm_matrix_instance_f32 dstC = {DATA_LINE_N, 1, testOutput};
相乘:
- auto a_Stat = arm_mat_mult_f32(&srcA, &srcB, &dstC);
就这么简单!
查看计算前计算后的结果:
- cout<<endl<<"Before Cacl:"<<endl;
- for(auto i=0; i<(srcA.numCols*srcA.numRows); ++i)
- {
- cout<<srcA.pData[i]<<' ';
- }
-
- tmpTick = g_Ticks;
- auto a_Stat = arm_mat_mult_f32(&srcA, &srcB, &dstC);
- cout<<endl<<g_Ticks-tmpTick<<" Cacl Res:"<<a_Stat<<endl;
- for(auto i=0; i<(dstC.numCols*dstC.numRows); ++i)
- {
- cout<<dstC.pData[i]<<' ';
- }
|