Qfplib和IQmath的对比测试

news/2024/10/18 23:08:03

Qfplib的介绍页面

https://www.quinapalus.com/qfplib.html
该浮点库使用针对cortex-m3优化的汇编代码实现了qfp_fadd,qfp_fsub,qfp_fmul,qfp_fdiv等函数,用以替代编译器内置的软浮点实现,和大多数数学库一样,Qfplib也需要你将代码中的符号运算替换成函数调用。
下面使用cortex-m4内核的单片机进行测试,虽然介绍页面有如下阐述It will also run on Cortex-M4 microcontrollers but is not optimised for these devices.,但是m4能支持m3的所有指令,将qfplib-m3.s文件中的.cpu cortex-m3改成.cpu cortex-m4直接进行编译也是可以通过的(不改也行)。

测试平台

目标芯片:AT32F415 Cortex-M4(No FPU),实际主频:144MHz,SRAM:32KB,FLASH等待4个周期。
编译器:arm gcc 13.2.Rel1,优化等级:O2
IQmath定点数使用iq15,Qfplib使用float

测试代码

#define CONST_PI_VAL 3.1415926f#define VECTOR_SIZE  600static _iq15 ResultVector[VECTOR_SIZE];
static _iq15 VectorA[VECTOR_SIZE];
static _iq15 VectorB[VECTOR_SIZE];static float ResultVectorF[VECTOR_SIZE];
static float VectorAF[VECTOR_SIZE];
static float VectorBF[VECTOR_SIZE];// IQ定点数 数组初始化
static void BenchmarkVectorIQArrayInit(void) {unsigned int index = 0u;for(index = 0; index < VECTOR_SIZE; index++) {VectorA[index] = _IQ15(1.0221f) * index;VectorB[index] = _IQ15(2.127f) * index;ResultVector[index] = 0;}
}// 浮点数 数组初始化
static void BenchmarkVectorQfpArrayInit(void) {unsigned int index = 0u;for(index = 0; index < VECTOR_SIZE; index++) {VectorAF[index] = qfp_fmul(1.0221f, index);VectorBF[index] = qfp_fmul(2.127f, index);ResultVectorF[index] = 0.0f;}
}// IQ定点数累加
static void VectorIQAdd(_iq15 *vectorA, _iq15 *vectorB, _iq15 *result) {unsigned int index = 0u;for(index = 0; index < VECTOR_SIZE; index++) {result[index] = vectorA[index]+ vectorB[index];}
}// 浮点数累加
static void VectorQfpAdd(float *vectorA, float *vectorB, float *result) {unsigned int index = 0u;for(index = 0; index < VECTOR_SIZE; index++) {result[index] = qfp_fadd(vectorA[index], vectorB[index]);}
}// IQ定点数乘法
static void VectorIQMultiply(_iq15 *vectorA, _iq15 *vectorB, _iq15 *result) {unsigned int index = 0u;for(index = 0; index < VECTOR_SIZE; index++) {result[index] = _IQ15mpy(vectorA[index], vectorB[index]);}
}// 浮点数乘法
static void VectorQfpMultiply(float *vectorA, float *vectorB, float *result ) {unsigned int index = 0u;for(index = 0; index < VECTOR_SIZE; index++){result[index] = qfp_fmul(vectorA[index], vectorB[index]);}
}// IQ定点数乘加
static void VectorIQScale(_iq15 *vectorA, _iq15 *vectorB, _iq15 *result) {unsigned int index = 0u;for(index = 0; index < VECTOR_SIZE; index++) {result[index] = _IQ15mpy(vectorA[index], _IQ15(CONST_PI_VAL));result[index] += vectorB[index];}
}// 浮点数乘加
static void VectorQfpScale(float *vectorA, float *vectorB, float *result) {unsigned int index = 0u;for(index = 0; index < VECTOR_SIZE; index++) {result[index] = qfp_fmul(vectorA[index], CONST_PI_VAL);result[index] = qfp_fadd(result[index], vectorB[index]);}
}// IQ定点数除法
static void VectorIQDiv(_iq15 *vectorA, _iq15 *vectorB, _iq15 *result) {unsigned int index = 0u;for(index = 0; index < VECTOR_SIZE; index++) {result[index] = _IQ15div(vectorA[index], vectorB[index]);}
}// 浮点数除法
static void VectorQfpDiv(float *vectorA, float *vectorB, float *result) {unsigned int index = 0u;for(index = 0; index < VECTOR_SIZE; index++) {result[index] = qfp_fdiv(vectorA[index], vectorB[index]);}
}int main(void) {uint32_t start, end, diff;BenchmarkVectorIQArrayInit();BenchmarkVectorQfpArrayInit();DWT->CYCCNT = 0x0;start = DWT->CYCCNT;VectorIQAdd(VectorA, VectorB, ResultVector);end = DWT->CYCCNT;diff = end - start;rt_kprintf("iq add, elapse:%d\n", diff);start = DWT->CYCCNT;VectorQfpAdd(VectorAF, VectorBF, ResultVectorF);end = DWT->CYCCNT;diff = end - start;rt_kprintf("qfp add, elapse:%d\n", diff);start = DWT->CYCCNT;VectorIQMultiply(VectorA, VectorB, ResultVector);end = DWT->CYCCNT;diff = end - start;rt_kprintf("iq mpy, elapse:%d\n", diff);start = DWT->CYCCNT;VectorQfpMultiply(VectorAF, VectorBF, ResultVectorF);end = DWT->CYCCNT;diff = end - start;rt_kprintf("qfp mpy, elapse:%d\n", diff);start = DWT->CYCCNT;VectorIQDiv(VectorA, VectorB, ResultVector);end = DWT->CYCCNT;diff = end - start;rt_kprintf("iq div, elapse:%d\n", diff);start = DWT->CYCCNT;VectorQfpDiv(VectorAF, VectorBF, ResultVectorF);end = DWT->CYCCNT;diff = end - start;rt_kprintf("qfp div, elapse:%d\n", diff);start = DWT->CYCCNT;VectorIQScale(VectorA, VectorB, ResultVector);end = DWT->CYCCNT;diff = end - start;rt_kprintf("iq scale, elapse:%d\n", diff);start = DWT->CYCCNT;VectorQfpScale(VectorAF, VectorBF, ResultVectorF);end = DWT->CYCCNT;diff = end - start;rt_kprintf("qfp scale, elapse:%d\n", diff);while(1) {osDelay(1000);}return 0;
}

原始日志

iq add, elapse:6023
qfp add, elapse:40991
iq mpy, elapse:11463
qfp mpy, elapse:32473
iq div, elapse:83931
qfp div, elapse:49770
iq scale, elapse:14447
qfp scale, elapse:71038iq add, elapse:6023
qfp add, elapse:40991
iq mpy, elapse:11463
qfp mpy, elapse:32473
iq div, elapse:83931
qfp div, elapse:49770
iq scale, elapse:14447
qfp scale, elapse:71038iq add, elapse:6023
qfp add, elapse:40991
iq mpy, elapse:11463
qfp mpy, elapse:32473
iq div, elapse:83931
qfp div, elapse:49770
iq scale, elapse:14447
qfp scale, elapse:71038iq add, elapse:6023
qfp add, elapse:40991
iq mpy, elapse:11463
qfp mpy, elapse:32473
iq div, elapse:83931
qfp div, elapse:49770
iq scale, elapse:14447
qfp scale, elapse:71038iq add, elapse:6023
qfp add, elapse:40991
iq mpy, elapse:11463
qfp mpy, elapse:32473
iq div, elapse:83931
qfp div, elapse:49770
iq scale, elapse:14447
qfp scale, elapse:71038

定点数加法和软浮点数加法

序号 iq add(us) qfp add(us)
1 41.823 284.659

定点数乘法和软浮点数乘法

序号 iq mpy(us) qfp mpy(us)
1 79.604 225.507

定点数除法和软浮点数除法

序号 iq div(us) qfp div(us)
1 582.854 345.625

定点数除法和软浮点数乘加

序号 iq scale(us) qfp scale(us)
1 100.326 493.319

总结

Qfp浮点库相比于IQ定点库性能提升

加法 乘法 除法 乘加
提升百分比 -580.6% -183.3% 40.7% -391.7%

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.ryyt.cn/news/73256.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈,一经查实,立即删除!

相关文章

transformers 推理 Qwen2.5 等大模型技术细节详解(一)transformers 初始化和对象加载(文末免费送书)

本文详细讲解 transformers 推理大语言模型的初始化过程,包括 Python 包搜索、LazyModule 延迟模块、模块搜索和 Python 包 API 设计美学……上周收到一位网友的私信,希望老牛同学写一篇有关使用 transformers 框架推理大模型的技术细节的文章。 老牛同学刚开始以为这类的文章…

UI开发概述

★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★➤微信公众号:山青咏芝(MaoistLearning)➤博客园地址:为敢技术(https://www.cnblogs.com/strengthen/ )➤GitHub地址:https://github.com/strengthen➤原文地址:https://www.cnblogs…

MiGPT让你的小爱音响更聪明

大家好,我是晓凡。 今天要给大家带来一个超级有趣的开源项目MiGPT。 这个项目,简直就是给小爱音箱装上了超级大脑,让你的小爱音箱更聪明。 想象一下,当小爱音箱接入大模型后,上知天文,下知地理,从“人工智障”秒变学霸。 一、什么是MiGPTMiGPT是一个由idootop团队开发的…

基于amis后端低代码平台

写这个平台是为了解决多年对于项目的困扰,不想碰到新项目就重新来,通过业务模块的积累,能进行模块化安装。新的项目只需要安装模块就能搭建一套完整的业务系统。amis-api 的所有基础代码都以模块的形式组合在一起。这些模块可以随时从数据库中安装或卸载。这些模块有两大目的…

数据采集与融合技术实验课程作业一

数据采集与融合技术实验课程作业一作业所属课程 https://edu.cnblogs.com/campus/fzu/2024DataCollectionandFusiontechnology作业链接 https://edu.cnblogs.com/campus/fzu/2024DataCollectionandFusiontechnology/homework/13286gitee码云代码位置 https://gitee.com/wang-qi…

C3P0 链子分析学习

C3P0 链子分析学习 概述 C3P0是一个开源的数据库连接池,它实现了数据源与JNDI绑定,支持JDBC3规范和实现了JDBC2的标准扩展说明的Connection和Statement池的DataSources对象。即将用于连接数据库的连接整合在一起形成一个随取随用的数据库连接池,使用它的开源项目有Hibernate…

鞅与停时定理

好用、神秘、很牛的东西!鞅与停时定理会随着呆猫做题更新一些,但是非题解部分的改动应该不大呆猫不会数学,要证明也是直接抄别人的,不如直接放一篇( 详细证明及介绍 主要写点,对鞅与停时定理的理解 定理与势能函数 对于一个随机过程\(\{X_0,X_1,...,X_t\}\),其中\(X_t\)…

20241018每日一题洛谷P2386

普及 每日一题 信息学竞赛 1206:放苹果 把M个同样的苹果放在N个同样的盘子里,允许有的盘子空着不放,问共有多少种不同的分法?(用K表示)5,1,1和1,5,1 是同一种分法。 第一行是测试数据的数目t(0<=t<=20)。以下每行均包含二个整数M和N,以空格分开。1<=M,N…