本帖最后由 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]<<' ';
}
|