一个有关0.0625℃的运算想到的问题

2020-01-19 19:42发布

发布: 2010-3-30 09:02 | 作者: cat_li | 来源: 电子爱好者社区
碰到一哥们号称挺NB的嵌入软件工程师,看了他的代码后就欧拉,事情是在一个只有4K代码的单片机接2个DS18B20测温传感器,都知道DS18B20输出数据只要乘以0.0625就是测量的温度值,这哥们说程序空间怎么也不够,实际上程序只有简单的采集两个DS18B20的数据转换成温度值,之后在1602液晶上显示,挺简单个程序,怎么也想不通为什么程序空间不够。只读了一下代码发现程序就没动脑子,真的用浮点库把DS18B20数据直接乘以0.0625了,那程序不超才怪呢,稍微动动脑子也会知道0.0625不就是1/16吗,把DS18B20的数据直接右移4位不就是了(当然要注意符号),这右移程序可十分简单还省空间,问题很好解决,空间自然也就够了。
    现在想来嵌入处理器确实是进步了,程序空间是越来越大,数据RAM空间也越来越大,导致很多人在写程序的时候真的是什么都不顾,借着C语言的灵活性真是纵横驰骋,压根也不讲个程序效率和可靠性。正如前些日子见到一孩子用ARM cortex-m3处理器给人接活写个便携表的1024点FFT算法,本身12位的AD系统,这小家伙直接到网上下载了浮点的FFT算法代码就给人加上了,结果整个程序死慢死慢的,人家用户可不买单啊,这时要动动脑子把数据直接变成乘以某个数变成整数后用定点FFT处理,之后再把数据除一下不就行了。速度自然也快了,而且也能省下空间。实际当中我们做嵌入软件很多时候犯懒都忽视程序执行效率问题,是都能实现功能,但有时候就是没法谈性能。我几次碰到这样的工程师,直接把传感器的信号放大后进嵌入处理器的AD,也不看看AD数据是否稳定有效,直接就进行FFT运算,那FFT结果真是热闹,不难看出混叠很严重,于是又机械地在FFT基础上再去衍生算法,系统程序越做越大,速度越做越慢。实际上也很简单的事,在传感器放大信号进AD之前来一级抗混叠滤波基本也就解决了,大有所谓嵌入软件高手的概念是程序几乎是万能,实在解决不了就换大程序空间更高速的处理器,整个恶性循环。
    经常听说现在流行低碳族,我想出 {MOD}的嵌入软件工程师最容易成为低碳一族,只要让代码高效那处理器频率自然可以灵活降下来,自然耗电也就少了,二氧化碳排放也就少了。想想目前到处都是嵌入处理器,代码条数看来也别有效果。
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
99条回答
langley
1楼-- · 2020-01-25 06:19
有意思
gliet_su
2楼-- · 2020-01-25 11:42
从LZ的文章可以看出
这都是软件不懂硬件给害的。
特别是从PC转嵌入式的人,以为在PC上OK了,到嵌入式板只是移植问题。
其实这里头受很多硬件资源的制约。

橘生淮南则为桔,生于淮北则为枳。
XA144F
3楼-- · 2020-01-25 12:01
 精彩回答 2  元偷偷看……
makesoft
4楼-- · 2020-01-25 17:53
回复【51楼】XA144F  
当然,还有的人叫嚣说c语言是王道,汇编可以完全抛弃。
-----------------------------------------------------------------------

我一直就这么主张,认为假如项目一定需要使用汇编,就是两个原因:
1、程序结构垃圾。
2、该换用速度更快容量更大的CPU。

90%的原因是第一条。
XA144F
5楼-- · 2020-01-25 19:20
52L:不尽然。

1.程序结构垃圾——如何定义“垃圾”?是编程者的算法不好还是C编译器的编译结果不好?

2.该换用速度更快容量更大的CPU——对我来说,接受客户要求定制仪器时,成本是不用考虑的,所以使用更快更大的CPU无所谓,靠的是高速优势来弥补因为代码冗长造成的效率低。但是对于批量生产的产品而言,成本是老板最关心的问题,即保证性能的同时要成本最低。

对单片机而言,现在的编译器可以做到很高的代码效率。简单的说,你用C写出一段代码,然后以你想象的方式翻译为最精简的汇编代码,然后将编译器输出的结果与之比较,看看有多大差别……

使用C语言的好处就是让编译器给你生成运算的代码,而不用自己去设计,比如让8位单片机完成16-16的乘除法运算,如果让用户用汇编来写,绝对的会让人头大。但并不是说C语言是万能的,比如这样一段C语言代码,在51单片机中编译的:

main()
        {
                char a,b,c,d;
                a=255;
                b=16;
                c=a/b;
                d=a%b;
        }

所有变量都是8位的字符型,所以对于51单片机而言是最好处理的,但是keil编译器如何应对的这个8-8除法运算?这是编译器生成的函数,可以直接得到商和余数:

                 C?SCDIV:
C:0x0003    C2D5     CLR      F0(0xD0.5)
C:0x0005    30F707   JNB      0xF0.7,C:000F
C:0x0008    B2D5     CPL      F0(0xD0.5)
C:0x000A    63F0FF   XRL      B(0xF0),#0xFF
C:0x000D    05F0     INC      B(0xF0)
C:0x000F    30E70C   JNB      0xE0.7,C:001E
C:0x0012    B2D5     CPL      F0(0xD0.5)
C:0x0014    F4       CPL      A
C:0x0015    04       INC      A
C:0x0016    84       DIV      AB
C:0x0017    63F0FF   XRL      B(0xF0),#0xFF
C:0x001A    05F0     INC      B(0xF0)
C:0x001C    8001     SJMP     C:001F
C:0x001E    84       DIV      AB
C:0x001F    30D502   JNB      F0(0xD0.5),C:0024
C:0x0022    F4       CPL      A
C:0x0023    04       INC      A
C:0x0024    22       RET      

如果照汇编来写,那只有几条指令(a在R6,b在R7,c在0x08,d在0x09):

MOV A,R6
MOV B R7
DIV AB
MOV 0x08,A
MOV 0x09,B

哪个更快?

我没有说要一定使用汇编或C语言,而是根据自己的需要来决定,或者说在C中加入汇编也是很不错的。

PS:对黑客而言,汇编语言中几条指令的效果如同催化剂,比调用几个API函数简单有效的多——比如“缓冲区溢出攻击”,只要找到缓冲区的溢出点,就将汇编指令对应的机器代码注入,那就可以控制别人的计算机了。所以汇编语言是黑客的必修课,只是知道用现成的软件的都不能称为黑客。
trueboy
6楼-- · 2020-01-25 23:08
lz:这事你别说的太细

一周热门 更多>