STM32 F407 带FPU float Q5.10 运算时间对比

最近在鼓捣FOC 就是那个无刷驱动

用STM32F407+DRV8305的方案

一开始自己写FOC的时候全用的float来计算,后来遇到一点(亿点点)问题,便在网上借鉴别(^C + ^V)人的代码,发现有人使用了定点数来运算,便好奇两种方式速度能差多少,就做了下对比(本来我以为定点可以秒杀浮点 哪怕有FPU)

平台:STM32F407 开FPU
freertos系统滴答频率是1000HZ,所以1tick就是1ms
keil关闭代码优化(开了也一样)

首先自己定义了Q5.10 的数据结构(我试了试Q10.21结果也是一样):

typedef int16_t Q5_10;
#define ToQ5_10(X) (X) * 1024         // 小数转浮点数
#define Q5_10M(X, Y) (X) * (Y) / 1024 // Q5.10乘法
#define Q5_10D(X, Y) (X) * 1024 / (Y) // Q5.10除法
#define Q5_10TOF(X) (X) / 1024.0f     // Q5.10转float

时间差计算函数:

uint32_t dt;
void tStart(void)
{
    dt = xTaskGetTickCount();
}

uint32_t tStop(void)
{
	//已经移植了Freertos 懒得重新建一个裸机工程 见谅
    return xTaskGetTickCount() - dt; 
}

__IO 来代替 volatile 关键字 (别问 问就是懒),定义所需变量

    __IO Q5_10 la = ToQ5_10(4.8), lb = ToQ5_10(4.0), lc = 0;
    __IO float fa = 4.8f, fb = 4.0f, fc;

以下测试均为10行语句循环0XFFFFF次
乘法对比测试函数:

    tStart();
    for (int i = 0; i < 0XFFFFF; i++)
    {
        lc = Q5_10M(la, lb);
        lc = Q5_10M(la, lb);

        lc = Q5_10M(la, lb);
        lc = Q5_10M(la, lb);

        lc = Q5_10M(la, lb);
        lc = Q5_10M(la, lb);

        lc = Q5_10M(la, lb);
        lc = Q5_10M(la, lb);

        lc = Q5_10M(la, lb);
        lc = Q5_10M(la, lb);
    }
    t = tStop();
    printf("Q *:%05d [%f]\n", t, Q5_10TOF(lc));

    tStart();
    for (int i = 0; i < 0XFFFFF; i++)
    {
        fc = fa * fb;
        fc = fa * fb;

        fc = fa * fb;
        fc = fa * fb;

        fc = fa * fb;
        fc = fa * fb;

        fc = fa * fb;
        fc = fa * fb;

        fc = fa * fb;
        fc = fa * fb;
    }
    t = tStop();
    printf("F *:%05d [%f]\n", t, fc);

除法测试对比函数:

 	tStart();
    for (int i = 0; i < 0XFFFFF; i++)
    {
        lc = Q5_10D(la, lb);
        lc = Q5_10D(la, lb);

        lc = Q5_10D(la, lb);
        lc = Q5_10D(la, lb);

        lc = Q5_10D(la, lb);
        lc = Q5_10D(la, lb);

        lc = Q5_10D(la, lb);
        lc = Q5_10D(la, lb);

        lc = Q5_10D(la, lb);
        lc = Q5_10D(la, lb);
    }
    t = tStop();
    printf("Q /:%05d [%f]\n", t, Q5_10TOF(lc));

    tStart();
    for (int i = 0; i < 0XFFFFF; i++)
    {
        fc = fa / fb;
        fc = fa / fb;

        fc = fa / fb;
        fc = fa / fb;

        fc = fa / fb;
        fc = fa / fb;

        fc = fa / fb;
        fc = fa / fb;

        fc = fa / fb;
        fc = fa / fb;
    }
    t = tStop();
    printf("F /:%05d [%f]\n", t, fc);

最后的结果如下:

Q *:00663 [19.199219]
F *:00532 [19.200001]
Q /:00970 [1.199219]
F /:01408 [1.200000]
数据格式 运算类型 所用时间 (MS) 结果
Q * 00663 [19.199219]
F * 00532 [19.200001]
Q / 00970 [1.199219]
F / 01408 [1.200000]

结果非常的啊没劲啊
可以看见
浮点乘法居然比定点乘法还要快!!(124.62%)

(当然我知道此处定点乘法其实是一次乘法和一次除法,但是实际情况不也得这样算吗?)

但是浮点除法比定点除法慢了不少(68.89%)

从此次实验还可观察出 能用乘法就别用除法 这种优化思路

以上便是这次无心的发现,令我十分惊奇,如果有什么错误的地方还请大佬们指出!!感谢

上一篇:JSP页面验证码实现


下一篇:React教程(二) : TypeScript