搜索
bottom↓
回复: 62

STM32 FFT优化最终版!速度逼近官方库,不再折腾了再搞剁手

  [复制链接]

出0入0汤圆

发表于 2014-4-7 10:17:42 | 显示全部楼层 |阅读模式
简介:这是一个在STM32F103开发板上做的FFT计算演示程序。程序以36kHz采样率从AD采集播放器的音频信号,然后以同样速率发送到DA通过喇叭播放。同时采下来的信号做FFT变换,在屏幕上显示两路音频波形以及频谱。

之前的程序(http://www.amobbs.com/forum.php? ... p;page=1#pid7424203)搞好之后本来不打算再弄了,但是在本坛另外一个帖子里面发现原来ST是有官方DSP库的,文档:http://www.st.com/st-web-ui/stat ... nual/CD00208762.pdf,里面的benchmark结果显示官方库的1024点FFT的速度居然达到了2.138ms,基本上是我之前程序速度的一倍,于是我又不淡定了。。。

去官网找了半天居然找不到那个库的下载,放狗一搜才发现有人说官方早就把那个库下架了,我估计是为了给带DSP指令集的F4系列让路。还好有老外放出了下载,下回来看了看,官方库确实是高度优化的,但是代价是非常固化,不灵活,实用性比较差。说白了就是跑分很好看,真正用那个库就不是那么回事了。主要体现在:

1、它的输入是1024点32bit的数组(以1024FFT为例),那么要用这个库你必须把数据拷贝到数组里面。在实时运算的时候基本上只有双缓冲这一个唯一的选择。而双缓冲是有缓冲切换开销的。我的程序是给个指针直接从循环缓冲区任意位置读数据的,任意缓冲区长度,自动回卷。

2、它用的是基-4的FFT,我用的是最简单的基-2的。基-4的FFT理论上运算量就比基-2的小,速度肯定快,但是代价是FFT点数必须是4^n,如果你要做512点或者2048点的FFT,那么你就没法用官方库了。另外看它的代码,实际上stm32做基-4的FFT寄存器是不大够用的,所以它里面有很多数据倒来倒去的过程,如果寄存器能像64位ARM那样有32个的话,官方库这个程序还可以更快~

3、它的输入输出是等长的,就是说你做1024点的FFT输入必须是1024点,如果你的输入小于这个长度,是没有任何性能提升的。我的程序可以随意设置输入长度,自动补零自动优化,当输入长度小于FFT点数的时候速度可以成倍提升。实际上我工作中用的FFT是4096点的,但是输入数据只有128点。所以这一点优化在实际应用中还是非常有用的。

好了,基本情况就是这样。我之前那个FFT是32位精度的,为了跟官方库比较,也跟着改为16位了。前前后后改了一个礼拜,每天都能发现一些新的地方可以提高速度,搞到现在觉得基本上到头了。也实在是不能再搞了,我觉得自己有点走火入魔了,再搞工作都要丢了~~

成果:视频演示的是跟官方benchmark一样的配置,1024入1024出,16bit,三角函数表在flash里。视频中关闭显示之后即是纯FFT循环,此时除了FFT之外只有AD,DA以及帧率显示。可以看到实测是365fps,也就是2.74ms,比官方的2.138ms还是差一点,残念。。。作为基-2的FFT,我基本上只能接受这样的结果啦,哎~~~~

http://v.youku.com/v_show/id_XNjk1NDE3NTI0.html

阿莫论坛20周年了!感谢大家的支持与爱护!!

一只鸟敢站在脆弱的枝条上歇脚,它依仗的不是枝条不会断,而是自己有翅膀,会飞。

出0入0汤圆

发表于 2014-4-7 10:29:12 | 显示全部楼层
沙发                  

出0入0汤圆

发表于 2014-4-7 10:29:45 | 显示全部楼层
强!!!!

出0入0汤圆

发表于 2014-4-7 10:35:00 | 显示全部楼层
厉害··超级棒····

出0入0汤圆

发表于 2014-4-7 10:36:03 来自手机 | 显示全部楼层
强人 顶你        

出0入0汤圆

发表于 2014-4-7 10:53:14 | 显示全部楼层
虽然没看懂.......但是感觉好强大的样子

出0入0汤圆

发表于 2014-4-7 11:11:17 来自手机 | 显示全部楼层
非常感兴趣。

出0入0汤圆

 楼主| 发表于 2014-4-7 12:00:23 | 显示全部楼层
啊?难道我写的帖子很难懂么?哪里写得不清楚你们倒是说说呀!>__<

出105入79汤圆

发表于 2014-4-7 12:08:25 | 显示全部楼层
楼主放出程序带大家学一下啊

出0入0汤圆

 楼主| 发表于 2014-4-7 12:24:26 | 显示全部楼层
qwe2231695 发表于 2014-4-7 12:08
楼主放出程序带大家学一下啊

纯汇编的,没啥好学的啊~我自己看着都烦,别人看更烦~

出100入101汤圆

发表于 2014-4-7 12:34:53 | 显示全部楼层
stm32,搞纯汇编,意义不大。汇编,多用在音视频编解码。

出0入0汤圆

发表于 2014-4-7 12:48:30 | 显示全部楼层
Borden 发表于 2014-4-7 12:24
纯汇编的,没啥好学的啊~我自己看着都烦,别人看更烦~

放出来看下其实也没什么,看不看得明白又是另外一回事

出0入0汤圆

发表于 2014-4-7 12:55:53 | 显示全部楼层
赞一个 真棒

出0入0汤圆

发表于 2014-4-7 13:04:54 来自手机 | 显示全部楼层
据说分裂基效率最高。

出0入0汤圆

发表于 2014-4-7 13:16:20 来自手机 | 显示全部楼层
mark      

出0入0汤圆

 楼主| 发表于 2014-4-7 13:20:08 | 显示全部楼层
笑笑我笑了 发表于 2014-4-7 13:04
据说分裂基效率最高。

分裂基在fpga上面效率最高,因为它理论计算量就是最少。但是在stm32上面不行,因为对称性的缺失,会有很多额外的处理,CM3的寄存器不够,用分裂基反而慢。CM3上最快的FFT就是基-4的。

出0入0汤圆

 楼主| 发表于 2014-4-7 13:25:25 | 显示全部楼层
fengyunyu 发表于 2014-4-7 12:34
stm32,搞纯汇编,意义不大。汇编,多用在音视频编解码。

不客气地讲,你说这话,是因为你不会。如果你C和汇编都用得很熟,再说这话就比较有分量。

出0入0汤圆

发表于 2014-4-7 13:48:40 | 显示全部楼层
干嘛不共享代码,让大家欣赏一下你的优化。

出0入0汤圆

发表于 2014-4-7 13:51:40 | 显示全部楼层
Borden 发表于 2014-4-7 12:24
纯汇编的,没啥好学的啊~我自己看着都烦,别人看更烦~

哈哈很委婉。其实大家不烦

出0入0汤圆

 楼主| 发表于 2014-4-7 14:18:16 | 显示全部楼层
本帖最后由 Borden 于 2014-4-7 15:06 编辑

既然有同学有兴趣,就给大家随便看看吧。核心的就不共享了,贴点无关紧要的献献丑得了

参数,变量和缓冲区定义:


ADC初始化,Dual模式,便于一次提取两个通道的数据:


TIM2和DAC初始化,TIM2用于触发ADC,DAC也同样配置为Dual模式便于同时发送:


ADC中断例程。这个写得有点笨,总觉得还可以优化一下,目前还没想到好的办法:


因为我前一个版本的ADC中断是这样的:


之所以在这个版本里面把去直流和移位放到中断里面做,是因为如果这里不做,那就要在FFT的时候做,而在FFT里面因为要多次读取ADC采样数据,那么就会每次读取都会算一次,很浪费时间。

右移4位是为了配合16位的FFT,不做右移的话,FFT的16位乘法会溢出。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出100入101汤圆

发表于 2014-4-7 14:19:53 | 显示全部楼层
Borden 发表于 2014-4-7 13:25
不客气地讲,你说这话,是因为你不会。如果你C和汇编都用得很熟,再说这话就比较有分量。 ...

是不会,没什么好客气的。

出0入0汤圆

发表于 2014-4-7 14:58:55 | 显示全部楼层
强人 顶你

出0入0汤圆

发表于 2014-4-7 15:22:35 | 显示全部楼层
源码什么时候拿出来分享一下啊!

出0入0汤圆

发表于 2014-4-7 15:38:44 | 显示全部楼层
高度赞扬楼主的钻研精神!!!

出0入0汤圆

发表于 2014-4-7 15:38:46 | 显示全部楼层
帅气 mark

出0入0汤圆

 楼主| 发表于 2014-4-7 16:14:24 | 显示全部楼层
bbsview 发表于 2014-4-7 15:38
高度赞扬楼主的钻研精神!!!

其实是强迫症晚期,跟淘宝剁手党一回事,根本停不下来~~

出0入0汤圆

发表于 2014-6-2 19:20:12 | 显示全部楼层
mark一下,挑战楼主~~~~~~

出0入0汤圆

 楼主| 发表于 2014-6-2 19:55:17 | 显示全部楼层
艾玛终于有人接招了好鸡冻~~~(✪ω✪)

出0入0汤圆

发表于 2014-6-3 11:55:38 | 显示全部楼层
楼主,你那是神马字体,好漂亮的样子

出0入0汤圆

 楼主| 发表于 2014-6-3 12:29:16 | 显示全部楼层
dmzy 发表于 2014-6-3 11:55
楼主,你那是神马字体,好漂亮的样子

呵呵你说代码吗?consolas呀!

出0入0汤圆

发表于 2014-6-3 12:47:58 | 显示全部楼层
Borden 发表于 2014-6-3 12:29
呵呵你说代码吗?consolas呀!

刚刚试了下,字体立马变漂亮了,太感谢了

出0入0汤圆

发表于 2014-6-21 05:17:35 | 显示全部楼层
楼主,你好,怎么提高fft变换的幅值精度呢,特别是低频部分的幅值精度,可以牺牲频率精度和相位精度。
我就想提高幅值精度,不知道咋整,望楼主提点,谢了。

出0入0汤圆

发表于 2014-6-21 11:00:49 | 显示全部楼层
不明觉历啊

出0入0汤圆

 楼主| 发表于 2014-6-21 11:51:12 | 显示全部楼层
SMC 发表于 2014-6-21 05:17
楼主,你好,怎么提高fft变换的幅值精度呢,特别是低频部分的幅值精度,可以牺牲频率精度和相位精度。
我就 ...

我也不知道啊,因为不知道你要干嘛呀!不同的应用有不同的处理啊。比如你可以改用32位乘法,提高FFT点数,提高输入值的点数等等,看哪些是你可以改进的咯。

出0入0汤圆

发表于 2014-6-30 11:21:50 | 显示全部楼层
强,  顶一下

出0入0汤圆

发表于 2014-7-1 18:32:32 | 显示全部楼层
Borden 发表于 2014-4-7 14:18
既然有同学有兴趣,就给大家随便看看吧。核心的就不共享了,贴点无关紧要的献献丑得了

参数,变量 ...

楼主您好,我是一个在校本科生,现在想接触一下CM3的汇编,以后遇到问题希望和您讨论。不知怎样才能联系到您。在论坛没有权限给您发私信,要不我留下我的邮箱吧~如果您有时间,希望您能给我回一封邮件。

我的邮箱是mmh_web@一六三.com

期待与您的进一步交流。

出0入0汤圆

发表于 2014-7-1 19:06:25 | 显示全部楼层
好东西啊                           

出0入0汤圆

发表于 2014-7-2 07:55:18 | 显示全部楼层
楼主,您的FFT程序是DIT的还是DIF的?
因为您提到“我的程序是给个指针直接从循环缓冲区任意位置读数据的,任意缓冲区长度,自动回卷。”,如果是DIT的话,存在数据倒序的问题,这样看来,如果采用DIF的话,可以使得输入数据用过之后就可以被覆盖了?

另外,麻烦楼主看一下37楼,多谢!

出0入0汤圆

发表于 2014-7-2 12:39:08 | 显示全部楼层
楼主,后来又想了想,不太明白您那个缓冲区的“自动回卷”是什么含义,是一个循环队列吗?

FFT的蝶形运算中,不管是DIT还是DIF,都会从原始输入数据中不按照递增的顺序来使用数据,那么,也必须在做完一个整个的FFT之后才能更新原始输入,这样的话,您的“自动回卷”意义在哪里?

出0入0汤圆

发表于 2014-7-7 07:48:00 | 显示全部楼层
楼主 强悍。。

出0入0汤圆

发表于 2014-7-7 08:05:51 | 显示全部楼层
标记,STM32 FFT优化最终版!速度逼近官方库,不再折腾了再搞剁手

出0入13汤圆

发表于 2014-7-7 08:37:20 | 显示全部楼层
楼主强悍啊,支持一个

出0入0汤圆

发表于 2015-9-2 15:51:54 | 显示全部楼层
厉害!!!!

出0入0汤圆

发表于 2015-10-21 23:58:28 | 显示全部楼层
Borden 发表于 2014-4-7 14:18
既然有同学有兴趣,就给大家随便看看吧。核心的就不共享了,贴点无关紧要的献献丑得了

参数,变量 ...

厉害的不要不要的

出0入0汤圆

发表于 2015-10-22 00:22:20 | 显示全部楼层
Mark,回头移植试试。

出0入0汤圆

发表于 2015-10-22 09:53:12 | 显示全部楼层
大虾,

出0入0汤圆

发表于 2016-4-13 16:51:23 | 显示全部楼层
谢谢分享!
好东西啊            

出0入0汤圆

发表于 2016-4-14 09:46:06 | 显示全部楼层
汇编那,楼主强

出0入0汤圆

发表于 2016-4-14 11:10:44 | 显示全部楼层
非常感兴趣。

出0入0汤圆

发表于 2018-7-18 11:59:23 | 显示全部楼层
厉害厉害,顶

出0入0汤圆

发表于 2018-7-18 12:34:28 | 显示全部楼层
记号  学习           

出0入10汤圆

发表于 2019-6-24 22:48:56 | 显示全部楼层
牛X 牛X汇编来搞

出0入0汤圆

发表于 2019-6-25 08:31:53 | 显示全部楼层
很好很实用,保存有空仔细看看

出0入0汤圆

发表于 2019-8-3 23:22:09 来自手机 | 显示全部楼层
牛人,强人,顶你

出150入0汤圆

发表于 2019-8-4 06:05:33 来自手机 | 显示全部楼层
官方的库发一下呗

出0入0汤圆

发表于 2019-8-4 11:07:16 | 显示全部楼层
汇编写的 牛x!

出10入0汤圆

发表于 2019-8-4 17:48:15 来自手机 | 显示全部楼层
b57203493 发表于 2014-4-7 13:51
哈哈很委婉。其实大家不烦

是啊,好委婉。

出0入0汤圆

发表于 2019-8-5 01:14:50 | 显示全部楼层

标记,STM32 FFT优化最终版!速度逼近官方库,不再折腾了再搞剁手

出0入0汤圆

发表于 2019-8-5 03:37:55 | 显示全部楼层
学习一下

出0入0汤圆

发表于 2019-8-5 09:19:15 | 显示全部楼层
又翻出来了,顶楼主一下。

出0入0汤圆

发表于 2019-8-5 11:05:58 | 显示全部楼层
牛逼,汇编看不懂,也不会,我用28335做过,频率没有那么高,效率没有计算过
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-3-29 23:53

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表