当前位置:首页 > 嵌入式 > 嵌入式分享
[导读]当你手握一块主频108MHz的GD32F103,满心期待它能跑出漂亮的运算成绩,却发现无优化编译下的Dhrystone跑分竟与隔壁同样主频的ARM Cortex-M3相差近三倍——这不是芯片的问题,是你的编译器在"偷工减料"。Dhrystone,这个诞生于1984年、由计算机科学家Reinhold P. Weicker设计的经典C语言整数运算基准测试程序,至今仍是衡量嵌入式MCU运算效率最直观的标尺。而将它移植到兆易创新GD32平台上,恰恰是一场代码与编译器之间的博弈。

当你手握一块主频108MHz的GD32F103,满心期待它能跑出漂亮的运算成绩,却发现无优化编译下的Dhrystone跑分竟与隔壁同样主频的ARM Cortex-M3相差近三倍——这不是芯片的问题,是你的编译器在"偷工减料"。Dhrystone,这个诞生于1984年、由计算机科学家Reinhold P. Weicker设计的经典C语言整数运算基准测试程序,至今仍是衡量嵌入式MCU运算效率最直观的标尺。而将它移植到兆易创新GD32平台上,恰恰是一场代码与编译器之间的博弈。

一、Dhrystone为何是MCU性能的"照妖镜"

Dhrystone测试的核心逻辑极其朴素:在单位时间内跑完多少次Dhrystone程序循环,再除以主频(MHz)得到DMIPS/MHz——即每兆赫兹每秒能执行多少百万条指令。1 DMIPS对应VAX-11/780小型机的1757次测试结果,是跨平台横向比较的通用货币。

这套程序只有三个核心文件:dhry_1.c(主程序入口)、dhry_2.c(算法子程序)、dhry.h(原型定义),代码量极小,却涵盖了整型运算、字符操作、数组处理、条件判断、循环、过程调用、字符串处理与指针操作——几乎复刻了嵌入式日常任务的全部编程模式。正因如此,它对编译器优化的敏感度高得惊人:实测中-O3优化比无优化性能提升可达3倍以上,不同编译选项下性能差异甚至高达26.8%。

二、GD32上的移植框架:三步搭建测试骨架

移植Dhrystone到GD32,本质是一次"最小化嵌入式适配"。根据兆易创新官方应用笔记AN164的指引,整个框架可拆解为三层:

第一层:时钟与计时基准。‌ GD32没有POSIX的clock()调用,必须用硬件定时器替代。典型做法是配置TIMER1为微秒级计数器——预分频器设为(APB1时钟/1MHz)-1,周期设为9999,再级联TIMER2做溢出扩展,实现64位微秒计时。计时精度直接决定DMIPS计算的可信度,±1微秒的误差在10秒测试周期内可以忽略。

第二层:串口输出重定向。‌ Dhrystone的结果通过printf输出,而GD32的printf默认走半主机模式或需重定向。在工程中实现_write函数,将标准输出映射到USART:

int _write(int fd, char *buf, int size) {

usart_data_transmit(USART0, (uint8_t *)buf, size);

return size;

}

同时需屏蔽主函数中原有的printf调用,仅在Dhrystone的ee_printf中触发,避免启动和停止定时器之间的串口干扰影响计时。

第三层:核心源码整合。‌ 将dhry_1.c、dhry_2.c、dhry.h与GD32对应的cpuidc.o、cpuida.o链接,修改dhry_1.c第31行的编译选项标识为"No Opt"、"Opt 2"或"Opt 3",即可切换不同优化等级。

三、编译器优化等级:从-O0到-O3的性能跃迁

真正的战场在Keil的"Options for Target"里。-O0无优化,代码忠实反映源码逻辑,适合调试但跑分惨不忍睹;-O1基础优化,平衡性能与可读性;-O2较高优化,适合发布;-O3最高优化,启用循环展开、函数内联等激进策略,但代码体积膨胀明显。

以GD32H759I-EVAL的480MHz主频为参照系,GD32F103在108MHz下的典型表现可类比推算:ARM Cortex-M3在72MHz下DMIPS/MHz达1.25,即90 DMIPS;而GD32F103主频高出50%,若启用Thumb-2指令集与硬件除法,DMIPS/MHz可逼近1.25甚至更高。实测中,开启-O2后D1处理器(RISC-V)成绩从112万次/秒飙至300万次/秒,GD32的ARM内核在-O3下同样会出现量级跃升。

更关键的细节是寄存器变量优化(-DREG参数),它强制局部变量驻留寄存器,对GD32这类资源受限的MCU尤为有效——减少内存访问意味着减少总线等待,直接拉升执行效率。

四、结果解读与工程启示

移植完成后,通过串口输出的Dhrystones/Sec除以1757得到DMIPS,再除以主频即为DMIPS/MHz。但必须清醒:直接比较不同架构的DMIPS需谨慎,编译器、缓存命中率、流水线深度都是变量。GD32F103对比STM32F103,主频更高、外设更丰富,但若编译器配置不当,性能优势会被完全抹平。

对于开发者而言,Dhrystone在GD32上的真正价值不在于跑分本身,而在于建立一套可复现的性能基准——用它验证编译选项、评估硬件选型、定位代码瓶颈。当你把-O2设为默认、把Thumb-2指令集打开、把硬件除法启用,GD32才会真正释放它108MHz主频下应有的计算野心。

本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除( 邮箱:macysun@21ic.com )。
换一批
延伸阅读

在GD32系列MCU运行FreeRTOS、RT-Thread等实时操作系统时,多任务并发访问共享资源(如UART、SPI总线、全局缓冲区)是常态。信号量(Semaphore)与互斥量(Mutex)是两种最常用的同步机制,...

关键字: 信号量 互斥量 GD32

在嵌入式实时系统中,任务之间如何高效通信、如何精确管理时间,是决定系统架构质量的核心问题。裸机编程中,超级循环配合中断的模型在复杂度上升时迅速失控——全局变量满天飞、中断嵌套混乱、时间管理依赖硬件定时器资源。μC/OS-...

关键字: μCOS-III GD32

程序跑了三天突然HardFault,DMA传着传着数据全乱了,I2C读到一坨0xFF——这些场景几乎是每个GD32开发者都经历过的"至暗时刻"。本文从程序原理、框架设计到具体实现,系统梳理GD32 C...

关键字: GD32 C语言开发

在电池供电的物联网设备中,MCU的待机功耗常常是决定续航时间的首要因素。一颗纽扣电池标称容量为200mAh,如果MCU始终运行在满速状态(功耗约20mA),理论续航仅10小时;而通过合理的睡眠模式配置,将待机功耗压低至μ...

关键字: C语言 GD32

异常处理的本质是"兜底"。‌ C语言没有try-catch,但GD32的硬故障异常(HardFault、BusFault、UsageFault、MemManage)天然提供了最后一道防线。当程序跑飞、...

关键字: C语言 GD32

USART(通用同步/异步收发器)是MCU与外部设备通信最基础也最常用的外设之一。在GD32系列MCU中,USART支持全双工异步通信,通过TX/RX两根信号线即可实现与PC上位机、蓝牙模块、其他MCU的数据交互。

关键字: C语言 GD32

对于嵌入式开发者来说,Keil MDK无疑是最熟悉的开发环境之一。但对于初次接触GD32系列MCU的工程师,即使是“点个灯”这样看似简单的任务,也可能在工程配置环节卡上半天。Keil社区版(MDK-Community)的...

关键字: Keil环境 GD32

模拟芯片是电子系统的神经网络,敏锐感知外界信号、精准调理电能流动、驱动机械的每一次跃动。从将传感器捕捉的微弱信号转化为清晰数据,到稳定电源为芯片提供不间断动力,再到指挥电机完成精确运动,模拟芯片无处不在,却往往隐于幕后。...

关键字: 兆易创新 GD32 模拟 信号链 PMIC

在一个电子系统中,微控制器和存储器可谓是其关键的组成部分,就像人的大脑一般,承载着计算、控制和数据存储的功能。而作为国产MCU和闪存龙头,兆易创新一直专注于在这两大领域的技术突破,并在芯片底层技术的基础之上,为汽车电子、...

关键字: 汽车电子 边缘计算 数字能源 GD32 兆易创新

大家好,我是小麦,今年沉迷炒股,7月份,经过股市经过几番沉浮,我也算是完美收场。但是想要逆袭,可以靠股市吗?如果是这种想法,我感觉赌的成分更大。我是不太赞同这种看法的。炒股可谓是几分欢喜几分愁啊,但是我深深感受到的不仅仅...

关键字: GD32 TCL
关闭