本帖最后由 QiaoJiannan 于 2016-6-8 10:41 编辑
写这篇文章纯属偶然,MCU benchmark有很多方法,且不同类型MCU benchmark方法完全不同,很难说谁好谁快? 不过,对电子爱好者来说,还是挺想知道“我所用的MCU”计算到底多快?本文,就从打酱油、非专业、大无畏精神出发,探讨入门级单片机计算性能到底如何、如何。
单片机能干的事儿很多啊,我通常用来:
- 控制个灯啊、空调啊、电视啊、小车啊神马的。
- 用传感器采集个温度啊、湿度啊、电压、电流、水流、人脸啊神马的。
- 显示输出:液晶、OLED、数码管;声音;电风扇神马的。
- 超低功耗:家里的中央控制系统基于树莓派,不到2W功耗。
- 便携。貌似自己做成的东西极少具有便携性。。。
在没有接触Arduino前都是用51倒腾,玩了有几年,觉得51是最适合电子爱好者用的芯片,简单、便宜、功能足够!但接触Arduino后才明白,原来还有这么个东东,比51先进得多,实在太好用了! 记得学51从二进制地址学起,不太好懂。后来用C开发经常问:“明明 c=a+b; print(c); 就行了,我干嘛要去学指令、寄存器、寻址?”高级语言屏蔽底层很多东西,让编程变得简单。并不是基础知识没用,这好比高等数学这道门槛(俺数学专业),你必须弄懂基础知识体系才能理解数学世界的美妙!但如果是经济学专业,不懂数学基础知识同样可以玩儿转经济学!你从中获得的乐趣跟你投入成正比。所以,我用单片机并不是科班那种需要弄懂MCU每个功能、每个模块,我用单片机就接接外设,完成我的想法而已。也许,只用到了单片机十分之一。说实话,极少使用单片机计算能力(话说这也不是单片机的强项呀),但如你要做个智能小车、四轴飞行器、PID控制,那就需要一定的计算能力了。
开始,只是简单想看看单片机运算有多快,偶然机会跟坛友交换了一块chipKIT Uno32(MIPS芯片),就想横向比较一下不同MCU的差别,于是就有了本文。其实,计算能力通过指令时钟周期来计算,科学准确,但对于不太精通底层知识的我,汇编犹如天书,真心看不懂啊!所以,还是用我自己的土办法测一下吧。
先说测试方法和原理:
- 只测试+、-、*、/、%五种操作符,uint8_t、uint16_t、uint32_t、uint64_t、float、double六种数据类型的性能。
首先测10000次空循环的时间,然后在循环中加入操作数,记录总的时间,减去空循环时间就是计算消耗的时间。 测试中由于有系统中断(Arduino、STM32都有Tick中断,51为计时也有中断),结果不会很准,话说也没指望它能有多准。。。 编译器优化参数 -O0,一开始测出来的运行时间都为“零”,彻底凌乱。研究之后方得知,编译器优化干掉空循环,需通过参数关闭优化。 不同芯片数据类型支持不一样,有些数据类型会缺失。例如Arduino Uno中的float和double是一样的,都是float;但32位架构MCU中的double是float宽度的两倍。
代码类似这样:
说个小故事。如不关闭测试优化选型,把全局变量定义成局部变量,加法、减法的测试时间为“零”,没错,10000次计算不到4微秒,这显然不可能。后来研究一番方得知编译器默认优化参数是-Os,很多计算直接优化了。。。。
测试用的板子:
- 传统的AT89C516,还有宏晶鼓吹的1T 51单片机(STC12C5A60S2)
- Arduino UNO(ATmega 328),Arduino Due(Atmel SAM3X8E,ARM架构的)
- chipKit Uno32(PIC32MX320F128 MIPS架构)
- ST Nucleo F0(STM32F030R8),Nucleo F1(STM32F103RB),都是ARM架构的
测试用开发环境:
- 51谈不上什么优化参数,我用的uVision 2。晶振用22.1184M,据说这个片子可以跑到40M,我就呵呵一下好了。
- Arduino IDE 1.6.9,图中2/3都是用Arduino环境,其中编译器参数需要修改platform.txt文件,默认是-Os(优化大小),改成-O0(完全不优化),这个要重启Arduino才能有效。。。
- STM用的是MDK 5.16,HAL库。没办法,对STM32真不熟,能捣鼓出结果很不错了!mbed计时函数有问题,F0、F1芯片无法得出微秒级时间,只好用HAL,话说用CubeMX生成代码还真挺方便的。
计时方法:
- 51用TIMER0计时,这个太简单了,每计数 12/22.1184 微秒啊!
- Arduino用系统micros(),根据两次记录的时间差,精度4微秒。
- STM用HAL库函数提供的HAL_GetTick(),通过HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/10000); 把计数器设为100微秒,再快会对计算有影响。
硬件说明:
- 部分芯片带硬件乘、除法器,啊,那个性能好的没话说。
- 32位MCU处理8/16/32位效果都是32位,但要求不高的地方,8位也够。
- 结果通过串口返回,Arduino串口超简单、STM32用HAL库串口通信也还行,这51串口啊,我就不说了。
测试结果:
分析:
综上所述,对于单片机选用哪一款都是可以的,STM32F1系列虽然综合最好,但学习门槛高,不易入门;51芯片虽历史悠久,性能可圈可点,但在Arduino的冲击下真没什么价值了。业余爱好者追求的是简单操作、快速搭建,Arduino完美的社区资源是任何其它芯片比不了滴!所以,建议非专业爱好者还是用Arduino来搭建原型,需要速度上MIPS芯片的chipKit,总有满足你的!
以上分析的是无优化性能,有点不公平。因为,实际上没人会无优化的编译,那么打开优化是什么样子呢?请看下图 (Arduino支持-O3,但考虑AVR片上Flash空间紧张,还是用-Os来说,附件有完整-O3的结果)
哇,性能全部飙升啊!平均都有3~5倍的提升,这也说明MCU的速度很依赖编译器!
- Arduino Due的性能比Uno快了近10倍,且Due的乘除性能不比STM32差,得益于ARM核心和硬件计算单元啊。
- MIPS架构总体最快,32位性能灰常优异,仅浮点比STM32F103略慢。
- STM32F103不愧是芯片之王,综合性能最好,尤其浮点处理能力!用于PID、四轴飞行器的计算很合适。
最后,真正的乐趣不是看谁跑得快,而是设计一段程序,让它能在完全不同的系统跑起来的那种成就感!这篇文章也是随手而写,测试内容并不是非常严谨,仅作参考。
扩展阅读:
在成文之前搜了下关于MCU的benchmark,才明白我可真是真井底之蛙!早有专业的测试算法工具,比如Dhrystone 。我也把他们在Arduino和MDK平台上都编译了一下,结果挺有意思的,具体结果就不贴了,大家可以自己试一下。如果真的想了解MCU的benchmark还得用这种成熟的方法,土方法只能娱乐而已。。。
Dhrystone Arduino下可运行:https://github.com/ghalfacree/Arduino-Sketches/tree/master/Dhrystone STM32下可运行:http://www.stm32duino.com/viewtopic.php?t=76
参考资料: 本文用到的代码和报告:http://pan.baidu.com/s/1i4KNxOx
|