OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 47024|回复: 41

分享一个浮点运算提高速度,减小代码量的小技巧!哦,尼玛,太兴奋了!

  [复制链接]

17

主题

342

帖子

0

精华

高级会员

Rank: 4

积分
544
金钱
544
注册时间
2014-4-24
在线时间
20 小时
发表于 2014-10-3 14:36:12 | 显示全部楼层 |阅读模式
       由于我后面的课题需要涉及较多的浮点运算,只熟悉f103,它不带FPU,所以软件浮点算法就显得很重要了。这几天在做些小研究和测试。
     今天又仔细研读了谭浩强的C语言书的数据类型章节,上面有说到c编译系统总将float类型转换成double类型来进行浮点运算,然而一般应用中7位有效数字的占32位的float类型已基本满足需求,若转为16位有效数字64位double类型岂不是没什么必要?速度岂不是会降低?
     今天将原子哥的内部温度传感器实验的浮点运算的代码作了个小小的改动,却是大大的改善,结果如下:
温度计算公式原代码为:    temp=(1.43-temp)/0.0043+25;        // 这句产生的代码量为1584字节
               改为单精度:     temp=(1.43f-temp)/0.0043f+25;       //这句产生的代码量仅为40字节!
        代码量减为原来的1/40,单从这个角度来看的话意味着计算速度有接近40倍的提升!!!具体速度未测试,但数十倍的提升应该有的。
       哦,尼玛!太兴奋了!
     可能有些同学还不知道1.43f的用法,c语言书中说了这是将浮点常量指定为单精度,若不加后缀f,将作双精度来处理。
速度能提升这么多,我想部分原因是因为stm32是32位的MCU,32位及其以下的数据处理时间差别不大,但对于大于32位的64位double类型肯定慢很多了~
    欢迎验证~~~

  
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

4

主题

133

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
3860
金钱
3860
注册时间
2016-6-11
在线时间
709 小时
发表于 2016-11-21 19:35:19 | 显示全部楼层
受教了。网上还有篇“让你的软件飞起来”可以读读。http://wenku.baidu.com/link?url= ... ber_pUeJekiCmDjRQsG
回复 支持 2 反对 0

使用道具 举报

10

主题

560

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1739
金钱
1739
注册时间
2014-6-27
在线时间
943 小时
发表于 2014-10-3 15:16:48 | 显示全部楼层
呵呵,不错,楼主一定收获很大吧,这种用法我都用了几年了,其实,C语言里面数据处理很重要的,但也是C语言基础,其实不仅仅是这些,还有很多细要注意的,我也分享一下曾经写过的一个函数,里面就有这样的方法:

//  ------------------------------------------------------------------------ 
// /* --------------------------- calcPT5541 --------------------------------- */
// /* ------------------------------------------------------------------------ */
void calcPTMS5541(float *pressure, float *temperature,u32 *p0, u32 *p1)
{
        float dt, off, sens;
        *p0 = *p0 & 0xFFFF;
        *(p0+1) = *(p0+1) & 0xFFFF;
        dt = -10000.0f + *(p0+1) - (8.0f * (*(p1+8)));
        off = 10000.0f + (*(p1+5)) + ( ( ( *(p1+7)-250.0f) * dt ) / 4096.0f);
        sens = 3000.0f + (*(p1+4) / 2.0f) + ( ( ( *(p1+6)+200.0f) * dt ) / 8192.0f);
        if(pressure!=NULL)
                *pressure = 1000.0f + (( sens * (*p0- off)) / 4096.0f);  
        if(temperature!=NULL)
        {
                if(dt<0.0f)
                { 
                        dt=dt-(dt/128*dt/128)/2;
                }
                else
                { 
                        dt=dt-(dt/128*dt/128)/8;
                }
                *temperature = ( 200.0f + (( dt * ( *(p1+9)+100.0f) ) / 2048.0f)) / 10.0f; 
        }
}
回复 支持 反对

使用道具 举报

17

主题

342

帖子

0

精华

高级会员

Rank: 4

积分
544
金钱
544
注册时间
2014-4-24
在线时间
20 小时
 楼主| 发表于 2014-10-3 15:20:23 | 显示全部楼层
回复【2楼】TinyBoy:
---------------------------------
谢谢大神~~~
回复 支持 反对

使用道具 举报

10

主题

560

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1739
金钱
1739
注册时间
2014-6-27
在线时间
943 小时
发表于 2014-10-3 15:27:24 | 显示全部楼层
回复【3楼】STM32VBT6:
---------------------------------
多多运用一下,你会发现,C语言学到这里已经釜底抽薪了,没有什么可以学的了,有人说C语言难,那是没有学到C语言基础最细节的东西,恰恰这些东西又是最基础的。
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165352
金钱
165352
注册时间
2010-12-1
在线时间
2108 小时
发表于 2014-10-3 21:59:07 | 显示全部楼层
谢谢分享。。。
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

36

主题

143

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
401
金钱
401
注册时间
2014-6-4
在线时间
89 小时
发表于 2014-10-4 20:50:41 | 显示全部楼层
我现在把所有的浮点运算都干掉,单片机有时候真不在行。
一路狂奔!
回复 支持 反对

使用道具 举报

0

主题

1

帖子

0

精华

新手上路

积分
22
金钱
22
注册时间
2014-7-25
在线时间
0 小时
发表于 2015-3-25 16:39:19 | 显示全部楼层
回复【4楼】TinyBoy:
---------------------------------
井底之蛙。c语言学到这里只能是皮毛而已。有本事直接用c写一个大型的系统软件出来。
回复 支持 反对

使用道具 举报

1

主题

215

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
254
金钱
254
注册时间
2013-9-23
在线时间
4 小时
发表于 2015-4-22 15:17:31 | 显示全部楼层
回复【5楼】正点原子:
---------------------------------
原子哥,请问stm32f103用MDK怎样做浮点运算,需要调用库文件吗? 另外,需要进行FFT运算,是不是像F4那样使用ST的DSP库呢?
回复 支持 反对

使用道具 举报

34

主题

805

帖子

4

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
1863
金钱
1863
注册时间
2011-3-29
在线时间
139 小时
发表于 2015-4-22 21:49:12 | 显示全部楼层
temp=(1.43-temp)/0.0043+25=1.43/0.0043+25-temp/0.0043=A-temp*N。
如果精度要求不高的话,可以简化为上面的形式,temp还可以用整数表示。
业余程序玩家。
回复 支持 反对

使用道具 举报

头像被屏蔽

65

主题

277

帖子

0

精华

高级会员

Rank: 4

积分
674
金钱
674
注册时间
2013-8-11
在线时间
29 小时
发表于 2015-4-22 22:19:08 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽
回复 支持 反对

使用道具 举报

3

主题

7

帖子

0

精华

新手上路

积分
40
金钱
40
注册时间
2014-11-26
在线时间
0 小时
发表于 2015-6-5 10:06:41 | 显示全部楼层
确实是好办法,我正在找,多谢楼主。
回复 支持 反对

使用道具 举报

126

主题

820

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1683
金钱
1683
注册时间
2012-10-28
在线时间
62 小时
发表于 2015-6-5 11:51:38 | 显示全部楼层
我做仪器设备时候,我的同事就是在数据后面加个F,一直没明白,现在明白了,多谢!
坚持学习!就能成功!
回复 支持 反对

使用道具 举报

72

主题

2711

帖子

2

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
3505
金钱
3505
注册时间
2014-8-4
在线时间
696 小时
发表于 2015-6-5 12:06:15 | 显示全部楼层
学习了、、、谢谢分享
以我资质之鲁钝,当尽平心静气、循序渐进、稳扎稳打之力。
回复 支持 反对

使用道具 举报

0

主题

3

帖子

0

精华

新手入门

积分
23
金钱
23
注册时间
2015-7-29
在线时间
0 小时
发表于 2015-8-26 20:40:13 | 显示全部楼层
楼主你好首先对于你的发现我测试了一下,定义temp为float类型,数据后面加f,代码量和运算速度提升了,对于定义temp为double类型数据后加f则没什么效果。
还有一个就是请教一下为什么1.43和0.0043后面可以加f,那么为什么25后面为什么不加f呢?
回复 支持 反对

使用道具 举报

0

主题

3

帖子

0

精华

新手入门

积分
23
金钱
23
注册时间
2015-7-29
在线时间
0 小时
发表于 2015-8-26 20:42:22 | 显示全部楼层
回复【2楼】TinyBoy:
---------------------------------

你好请问 dt = -10000.0f + *(p0+1) - (8.0f * (*(p1+8))); 
        off = 10000.0f + (*(p1+5)) + ( ( ( *(p1+7)-250.0f) * dt ) / 4096.0f); 
        sens = 3000.0f + (*(p1+4) / 2.0f) + ( ( ( *(p1+6)+200.0f) * dt ) / 8192.0f); 
中为什么不是所有的数据后面都加f呢,还是说整数后面不加f,浮点数后面才加f。
回复 支持 反对

使用道具 举报

10

主题

560

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1739
金钱
1739
注册时间
2014-6-27
在线时间
943 小时
发表于 2015-8-26 21:05:24 | 显示全部楼层
回复【15楼】蹦跑的小鸡:
---------------------------------
首先,结果是带小数的,那么用单浮点就可以满足了,因为小数默认是双浮点的,双浮点计算比较耗时间,所以用单浮点,所有的小数都加f,只要有一个没加,运算到它的时候,又转换成双浮点了。其次,既然有单浮点数了,不是浮点数的数是什么就是什么,在和浮点运算的时候,自然会转换成浮点数再运算的。
回复 支持 反对

使用道具 举报

0

主题

3

帖子

0

精华

新手入门

积分
23
金钱
23
注册时间
2015-7-29
在线时间
0 小时
发表于 2015-9-3 09:28:18 | 显示全部楼层
回复【16楼】TinyBoy:
---------------------------------
好的明白了,thank u very much.
回复 支持 反对

使用道具 举报

2

主题

13

帖子

0

精华

初级会员

Rank: 2

积分
82
金钱
82
注册时间
2015-6-12
在线时间
13 小时
发表于 2015-11-9 13:46:10 | 显示全部楼层
我习惯将常量的除法变为乘法。如上面的例子,可以这样

const float a = 1.0 / 0.0043;

temp= (1.43-temp) * a + 25;

一般乘法运算比除法快,只要是除以一个常量的,都可以转成乘法。不过在STM32上我没测试过究竟提高了多少速度。
回复 支持 反对

使用道具 举报

1

主题

14

帖子

0

精华

初级会员

Rank: 2

积分
108
金钱
108
注册时间
2015-2-26
在线时间
26 小时
发表于 2016-5-31 08:56:11 | 显示全部楼层
如果是数组呢? 或者进行强制类型转换可不可以?
回复 支持 反对

使用道具 举报

0

主题

8

帖子

0

精华

初级会员

Rank: 2

积分
51
金钱
51
注册时间
2016-1-21
在线时间
20 小时
发表于 2016-5-31 09:22:54 | 显示全部楼层
mark备用
回复 支持 反对

使用道具 举报

2

主题

27

帖子

0

精华

初级会员

Rank: 2

积分
95
金钱
95
注册时间
2014-7-1
在线时间
11 小时
发表于 2016-10-8 10:56:19 | 显示全部楼层
赞一个,确实有用
回复 支持 反对

使用道具 举报

30

主题

1170

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1993
金钱
1993
注册时间
2016-2-16
在线时间
527 小时
发表于 2016-10-20 14:37:53 | 显示全部楼层
确实有用,看来以后32位的MCU,多用float,运算加f
回复 支持 反对

使用道具 举报

1

主题

8

帖子

0

精华

初级会员

Rank: 2

积分
56
金钱
56
注册时间
2013-11-19
在线时间
4 小时
发表于 2016-11-21 17:36:11 | 显示全部楼层
,上面分享的都是大神啊!!最近接触到了DSP,看到楼上几位的分享很是眼前一亮,有两个疑问,望哪位大神不吝指教下:
1.是不是不带FPU的处理器都是定点处理器啊? 比如定点数值信号处理器 C55XX系列的,比如51单片机,再比如RAM常用的Cortex-M3内核处理器!
2.对于定点处理器上面大神分享的经验是不是都通用的,还是根据编译器而定的?
回复 支持 反对

使用道具 举报

6

主题

80

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
358
金钱
358
注册时间
2016-9-24
在线时间
80 小时
发表于 2016-11-21 20:01:31 | 显示全部楼层
标记备用
回复 支持 反对

使用道具 举报

1

主题

18

帖子

0

精华

初级会员

Rank: 2

积分
171
金钱
171
注册时间
2016-5-22
在线时间
66 小时
发表于 2019-12-29 17:02:21 | 显示全部楼层
好东西
回复 支持 反对

使用道具 举报

0

主题

30

帖子

0

精华

初级会员

Rank: 2

积分
73
金钱
73
注册时间
2019-9-5
在线时间
28 小时
发表于 2019-12-30 20:55:13 | 显示全部楼层
真是好东西,学习了
回复 支持 反对

使用道具 举报

1

主题

34

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1614
金钱
1614
注册时间
2019-4-22
在线时间
310 小时
发表于 2019-12-31 16:08:39 | 显示全部楼层
mark感谢
回复 支持 反对

使用道具 举报

1

主题

12

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
258
金钱
258
注册时间
2019-1-6
在线时间
42 小时
发表于 2020-4-14 11:06:22 | 显示全部楼层
Mark 谢谢!
回复 支持 反对

使用道具 举报

0

主题

4

帖子

0

精华

新手入门

积分
5
金钱
5
注册时间
2020-4-14
在线时间
0 小时
发表于 2020-4-14 16:04:10 | 显示全部楼层
感谢分享
回复 支持 反对

使用道具 举报

0

主题

60

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
3167
金钱
3167
注册时间
2020-4-9
在线时间
291 小时
发表于 2020-5-26 10:17:33 | 显示全部楼层
受教啦
回复 支持 反对

使用道具 举报

21

主题

217

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2124
金钱
2124
注册时间
2017-12-11
在线时间
460 小时
发表于 2020-5-26 10:36:43 | 显示全部楼层
感谢分享!
回复 支持 反对

使用道具 举报

0

主题

7

帖子

0

精华

初级会员

Rank: 2

积分
56
金钱
56
注册时间
2019-6-22
在线时间
11 小时
发表于 2020-6-6 16:06:26 | 显示全部楼层
谢谢分享!
回复 支持 反对

使用道具 举报

2

主题

29

帖子

0

精华

初级会员

Rank: 2

积分
95
金钱
95
注册时间
2019-10-22
在线时间
17 小时
发表于 2020-6-19 15:27:30 | 显示全部楼层
学习了,下次试试
回复 支持 反对

使用道具 举报

7

主题

88

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
273
金钱
273
注册时间
2015-1-10
在线时间
69 小时
发表于 2020-10-19 12:00:47 | 显示全部楼层
赞一个,受教了
回复 支持 反对

使用道具 举报

1

主题

14

帖子

0

精华

初级会员

Rank: 2

积分
124
金钱
124
注册时间
2020-9-1
在线时间
24 小时
发表于 2020-10-19 17:09:43 | 显示全部楼层
受教了
回复 支持 反对

使用道具 举报

0

主题

13

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
282
金钱
282
注册时间
2017-1-8
在线时间
123 小时
发表于 2020-10-19 22:45:53 | 显示全部楼层

受教了,确实如此
回复 支持 反对

使用道具 举报

3

主题

1906

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
4100
金钱
4100
注册时间
2018-8-14
在线时间
695 小时
发表于 2020-12-29 18:24:37 | 显示全部楼层
本帖最后由 edmund1234 于 2020-12-29 18:26 编辑
ofourme 发表于 2015-4-22 21:49
temp=(1.43-temp)/0.0043+25=1.43/0.0043+25-temp/0.0043=A-temp*N。如果精度要求不高的话,可以简化为上面 ...

总有这样的误解, 认为float比整数运算的精度高, 其实不尽是(省去运算最后的转换,这里就直接称其为整数运算)

应该说float比整数的动态范围更宽, float的精度只用了23位, 而在某个指定的范围内, int的精度是31位

比如你要建一sin table, 动态范围就只是 -1.0 ~ 1.0这个区间, 用int运算, 其精度是 0.47x10^-9, 而float 的精度只有119.2 x 10^-9

所以还是要看应用时的动态范围, 就一般应用而言论, 经常都会是用int运算的精度比float高的, 而且快了不是一点点
回复 支持 反对

使用道具 举报

9

主题

245

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1221
金钱
1221
注册时间
2014-11-25
在线时间
173 小时
发表于 2020-12-30 08:57:13 | 显示全部楼层
可是你的精度损失了呀,有舍有得
回复 支持 反对

使用道具 举报

4

主题

9

帖子

0

精华

新手上路

积分
28
金钱
28
注册时间
2021-2-26
在线时间
3 小时
发表于 2021-3-13 16:17:09 | 显示全部楼层
看了你得帖子,我得到启发!原先我从网上拷贝了浮点得函数,怎么运算出来都是整数,后来加了f后,输出都正常了!
回复 支持 反对

使用道具 举报

5

主题

35

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
298
金钱
298
注册时间
2017-12-23
在线时间
76 小时
发表于 2023-1-31 23:49:03 | 显示全部楼层
怎么算出来每一句代码产生的代码量是多少的?
回复 支持 反对

使用道具 举报

3

主题

800

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
3775
金钱
3775
注册时间
2017-3-7
在线时间
1645 小时
发表于 2023-2-1 12:11:39 | 显示全部楼层
Baldwin0411 发表于 2023-1-31 23:49
怎么算出来每一句代码产生的代码量是多少的?

看生成的汇编文件,或者调试的时候看反编译指令
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2024-11-24 18:35

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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