首页 > 其他分享 >Qfplib和IQmath的对比测试

Qfplib和IQmath的对比测试

时间:2024-10-18 22:59:53浏览次数:6  
标签:index elapse iq qfp result 测试 Qfplib IQmath SIZE

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  600

static _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:71038

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:71038

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:71038

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:71038

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: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%

标签:index,elapse,iq,qfp,result,测试,Qfplib,IQmath,SIZE
From: https://www.cnblogs.com/yanye0xcc/p/18473677

相关文章

  • 测试题
    1.嵌入式软件开发构建阶段的第一步、第二步和第三步分别是(A)A.编译、链接、定址B.链接、编译、定址C.打包、定址、编译D.编译、定址、链接tips:编译:在这一阶段,编译器分析源代码并生成中间或目标代码文件。编译器会进行语法检查、类型检查和优化。链接:链接器将多个编译后的......
  • 编写自定义dbt通用数据测试
    dbt默认提供了NotNull,Unique,Relationships,和AcceptedValues四个通用数据测试,这些测试被称为”schema测试“,底层这些通用测试就是类似宏的测试块。本文首先介绍内置通用测试,然后介绍如何自定义通用测试,最后还实践如何覆盖内置通用测试的功能。内置数据测试......
  • 为了避免下一次重大中断,我们需要持续测试
    自去年7月CrowdStrike/Microsoft大规模中断以来的几个月里,我们了解到了很多问题所在。一家大型网络安全提供商为其广泛部署的企业端点保护产品推出了一个有缺陷的更新。尽管(错误地)批准发布,但该更新导致全球的Windows系统崩溃,并阻止它们从重启中自然恢复。短短几分钟内,全......
  • 《刚刚问世》系列初窥篇-Java+Playwright自动化测试-3-启动浏览器(详细教程)
    1.简介 通过前边两篇文章跟随宏哥学习想必到这里已经将环境搭建好了,今天就在Java项目搭建环境中简单地实践一下: 启动两大浏览器。按市场份额来说,全球前三大浏览器是:IE.Firefox.Chrome。但是微软已经在Win10中不维护IE浏览器了,用Edge浏览器代替或者兼容IE模式的浏览器,因此宏哥这......
  • 优秀图书推荐《单元测试:原则、模式和实践》与要点解析
    一.单元测试历史背景     单元测试在软件开发中已经存在了几十年,但直到21世纪初,它才成为软件开发过程中的一个标准实践。随着敏捷开发方法的兴起,单元测试变得更加重要,因为它支持快速迭代和持续集成。VladimirKhorikov的书《单元测试:原则、模式和实践UnitTesting:Principl......
  • 高压1500kW 海洋平台测试交流干式负载箱的应用
    海洋平台是石油和天然气勘探开发的重要设施,其稳定性、安全性和可靠性对整个生产过程至关重要。为了确保海洋平台的正常运行,需要对其进行定期的检测和维护。在这个过程中,高压1500kW交流干式负载箱发挥着重要的作用。高压1500kW交流干式负载箱是一种能够模拟实际负载的设备,主要用于......
  • Burp Suite Professional 2024.9 for macOS x64 & ARM64 - 领先的 Web 渗透测试软件
    BurpSuiteProfessional2024.9formacOSx64&ARM64-领先的Web渗透测试软件世界排名第一的Web渗透测试工具包请访问原文链接:https://sysin.org/blog/burp-suite-pro-mac/查看最新版。原创作品,转载请保留出处。作者主页:sysin.orgBurpSuiteProfessionalTheworld......
  • 黑白盒测试的特点和优缺点及比较
    黑盒和白盒是软件测试中的两种基本测试方法,它们在测试的角度和方法上有显著区别。黑盒测试定义黑盒测试是一种不考虑内部实现细节的测试方法。测试人员只关注输入和输出,而不需要了解程序的内部结构和逻辑。特点关注输入和输出:测试人员根据功能说明书或需求文档,设计测试用......
  • 安全测试的漏洞类型
    目录一、安全测试的定义二、安全测试的分类1、静态扫描2、内存扫描3、动态安全测试三、安全测试主要关注哪些方面的漏洞漏洞一:SQL注入漏洞二:XSS 漏洞三:暴力破解漏洞四:文件包含文件上传漏洞漏洞五:越权漏洞漏洞六:信息泄露四、预防XSS预防暴力破解预防文件上传......
  • pix2pix模型测试时不使用model.eval()
    目录pix2pix特殊之处理论基础:model.eval()、model.train()、withtorch.no_grad()model.eval()、model.train()withtorch.no_grad()实际操作参考资料pix2pix特殊之处pix2pix模型在测试时与众不同的特点:1、使用dropout,引入随机性,否则容易无论什么输入都生成一样的图2、使用Bat......