当前位置: 首页 > news >正文

【转载】RISC-V IDE MRS2 代码编译 : 通过配置FPU提升浮点运算性能

本文介绍嵌入式中的浮点数与青稞系列芯片的FPU硬件浮点单元,并说明如何使用MRS2配置FPU提升浮点性能以及串口打印浮点数。

一、单精度浮点数与双精度浮点数

嵌入式处理器使用的浮点数遵循 IEEE 754 标准。这套标准规定了一种将实数编码为有限位二进制的方式,其核心思想是把一个数分解为三个独立的字段:符号位(Sign)、指数位(Exponent)和尾数位(Mantissa)。这三个字段在内存中是紧密排列的。

值 = (−1)^S × 2^(E − bias) × (1 + Mantissa)

浮点数一般根据其占用的位宽度分为单精度浮点数(float)与双精度浮点数(double)。其在内存中的布局如下所示。

单精度(float)的位布局

S(符号)Exponent(指数)Mantissa(尾数)
1 位8位 · bias=12723位

双精度(double)的位布局

S(符号)Exponent(指数)Mantissa(尾数)
1 位11位 · bias=102352位

单精度float占用 4 字节,能够提供约 7 位有效十进制数的精度,数值范围覆盖 ±3.4×10³⁸。双精度double则占用 8 字节,精度提升到约 15~16 位,范围扩展到 ±1.7×10³⁰⁸。从数学上看,double显然更精确,但在嵌入式领域,精度优势无法弥补它花费的巨大开销,优先使用float才是更好的选择。

二、浮点数常量

嵌入式开发中浮点数有一个非常容易被忽视的细节。

C 语言里所有不带后缀的浮点字面量,比如0.01、3.14,其类型默认是double而不是float 。

例如一个简单的浮点计算并赋值的代码:

float x = 3.14 * 2.0;

3.14和2.0都没有f后缀,所以编译器会把这两个常量都当作double来处理。由于赋值给float变量,因此在以double运算后编译器会进行一次截断,将64位运算结果截断为32位的float。

还有一种混合的情况:

float x = 3.14f * 2.0;

3.14添加了f后缀,显式定义为float常量,2.0未加f后缀,依然默认为double常量。C 语言规定,当 float 和 double 混合运算时,float 那一方会被隐式提升为 double,然后以 double 精度完成乘法,最后再截断回 float。也就是说,只要包含一个未加后缀的操作数,表达式就会以double进行运算。

建议给所有浮点数添加后缀f显式声明其为float常量。

float x = 3.14f * 2.0f;

此时由于全部操作数都为float,表达式会以float进行运算。在使用软件浮点库中的函数进行运算时似乎与使用double没有太大差别,但当芯片内置支持单精度运算的硬件浮点单元(FPU)时,float运算会有巨大的提升。

三、FPU 硬件浮点单元

FPU(Floating Point Unit,浮点运算单元)是处理器中专门用于执行浮点数运算的硬件模块。利用软件浮点库进行浮点运算时,调用相关的浮点运算函数进行模拟,一般需要十几到几十条指令才能完成。而在FPU的帮助下,加法、乘法等基础浮点运算可以在单个时钟周期内完成,极大提高浮点运算效率。

WCH部分芯片支持FPU,例如青稞V3F\V5F内核芯片(CH32H416、CH32H415、CH32H417)和青稞V4F内核芯片(CH32V303、CH32V305、CH32V307、CH32V317)。以上型号支持RISC-V F指令集,拥有F0-F31共32个浮点寄存器,用于存储单精度浮点指令所需数据。

使用MRS2开发时,通过几步配置即可使用芯片的FPU提高浮点运算性能。

1.勾选浮点扩展与ABI

打开工程配置Build Settings->Tool Settings->Target Processor页面:

Floating point选择Single precision extension(RVF)单精度浮点扩展;

Floating point ABI选择Single precision(f)单精度浮点。

2.勾选浮点优化选项

打开工程配置Build Settings->Tool Settings->Optimization页面

勾选Single precision constants(-fsingle-precision-constant)选项。

开启这个选项之后,会将源码里所有不带后缀的浮点常量强制当作float来处理,效果等同于在每一个浮点常量后手动加了f。可确保浮点运算为单精度,充分利用FPU硬件浮点单元提高浮点运算性能。

四、浮点数打印

嵌入式开发环境一般默认使用裁剪过的C库(如newlib-nano),出于代码体积考虑,printf的实现删去了浮点格式化的支持。如果直接调用printf("%.2f", val) ,串口浮点数输出为空。

若需通过串口打印浮点数,需要链接相应的浮点打印库。

MRS2中通过勾选链接选项,选择合适的浮点打印库,即可在串口打印浮点数。

打开工程配置Build Settings->Tool Settings->GNU RISC-V Cross Linker->Miscellaneous页面。

勾选Use float with nano printf(-u _printf_float)会使用标准库newlib-nano中的浮点打印函数,支持更全面的输出格式,相应的链接库体积会稍大;

勾选Use wchprintfloat(-lprintfloat)会使用MRS提供的精简浮点打印函数,仅保留常用的输出格式,能够有效减小代码体积。

同时,Use wchprintfloat(-lprintfloat)还可支持64位数据打印。

根据自身需求选择合适的选项即可。推荐使用Use wchprintfloat选项,基本可满足常见浮点打印格式需求,且代码体积优势较为明显。

————————————————
版权声明:本文为CSDN博主「MounRiver_Studio」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_36353650/article/details/163241703

http://www.cnnetsun.cn/news/3845421.html

相关文章:

  • G-Helper终极指南:如何免费解锁华硕笔记本完整性能控制功能
  • 基于RAG与Cherry Studio构建高精度私有AI知识库实战指南
  • 隐私计算≠数据不出域?深度拆解AI训练中11种隐式信息泄露通道(含梯度反演攻击复现实验代码)
  • 高压降压设计实战:从选型误区到Hi9214高效稳定电源方案
  • 树莓派SPI1接口配置MCP2515 CAN总线控制器完整指南
  • 从黑盒到白盒:逆向分析赛尔号通信协议的技术实践
  • 「2026 最新」VoxCPM2 整合包v4|34K Star 开源 AI 语音合成 TTS|声音克隆与多语言方言
  • 从数据库到语义大脑:基于OpenClaw.NET的本体工程实践
  • ControlNet技术解析:精准控制AI图像生成
  • 工业通信基石:Modbus TCP协议解析与实战开发指南
  • 从零搭建NFS共享存储:原理、配置与排错全指南
  • TikTok Shop上架软件:20核高并发不抢焦的云端挂机实战
  • STM32 工程模块化开发规范|头文件分层、引脚宏统一管理、高可移植项目架构实战
  • 本地化开发工具链部署指南:基于Docker Compose的Vibe Coding实践
  • 技术选型避坑指南:从概念到实践,理性评估10类开发工具
  • 从AI代码生成到工程化交付:构建可控的AI编程工作流
  • Unity URP体积云与天气系统:从原理到实战的Altos插件深度解析
  • 闲鱼MCP服务
  • TEMU采集工具:接口直取+DOM穿透,双层突破平台反爬体系
  • [开源项目]CreatorHub 本地运行的多平台内容管理面板,支持 抖音 / 小红书 / 快手 / 视频号
  • Unity独立开发者指南:免费资源整合与高效利用方法论
  • Unity二次元桌宠开发实战:从Live2D模型到桌面交互全流程
  • Linux运维实战:YUM源配置从本地到私有仓库全解析
  • 距离滔搏失去耐克,还剩5个月
  • 大差法详解:流水施工工期计算原理与Excel实操指南
  • 游戏脚本开发入门:从图色模拟到自动化逻辑构建
  • 聆犀AI录音卡 x WorkBuddy:一小时,把真实业务需求跑成能用的工具原型
  • SQL JOIN七种连接方式详解:从原理到实战避坑指南
  • 基于SVM与Simulink的风力涡轮机故障检测:从原理到工程实现
  • DETR:基于Transformer的端到端目标检测原理与实战指南