一、FPU的启用
FPU 即浮点运算单元(Float Point Unit)。浮点运算,对于定点 CPU(没有 FPU 的 CPU)来说必须要按照 IEEE-754 标准的算法来完成运算,是相当耗费时间的。而对于有 FPU 的 CPU来说,浮点运算则只是几条指令的事情,速度相当快。
STM32G4 属于 Cortex M4F 架构,带有 32 位单精度硬件 FPU,支持浮点指令集,相对于Cortex M0 和 Cortex M3 等,高出数十倍甚至上百倍的运算性能。
二、实验
下面基于STM32G474VET6,使用HAL库函数,在Keil MDK 5环境下,完成上述需求。
开启定时器,设置为基础计数模式,时钟源为内部时钟,主频170MHZ,不分频,每个时钟周期约为5.88ns。
测试函数代码:分别进行重复的加减乘除浮点运算,串口发送运算前后定时器计数值CNT的差值
void float_operations_test(void)
{volatile float a = 1.23f;volatile float b = 4.56f;volatile float result_add, result_sub, result_mul, result_div;uint32_t start_time, end_time;// 开始定时器HAL_TIM_Base_Start(&htim2);printf("其中a=1.23 b=4.56,重复进行10次运算,在170Mhz每个时钟周期为: %lu ns\n", 6);// 测试加法start_time = __HAL_TIM_GET_COUNTER(&htim2);
// for (int i = 0; i < 10; i++)
// {result_add = a + b;
// }end_time = __HAL_TIM_GET_COUNTER(&htim2);printf("加法时间: %lu 个时钟周期\n", end_time - start_time);printf("加法结果: %f\n", result_add);// 测试减法start_time = __HAL_TIM_GET_COUNTER(&htim2);
// for (int i = 0; i < 10; i++)
// {result_sub = a - b;
// }end_time = __HAL_TIM_GET_COUNTER(&htim2);printf("减法时间: %lu 个时钟周期\n", end_time - start_time);printf("减法结果: %f\n", result_sub);// 测试乘法start_time = __HAL_TIM_GET_COUNTER(&htim2);
// for (int i = 0; i < 10; i++)
// {result_mul = a * b;
// }end_time = __HAL_TIM_GET_COUNTER(&htim2);printf("乘法时间: %lu 个时钟周期\n", end_time - start_time);printf("乘法结果: %f\n", result_mul);// 测试除法start_time = __HAL_TIM_GET_COUNTER(&htim2);
// for (int i = 0; i < 10; i++)
// {result_div = a / b;
// }end_time = __HAL_TIM_GET_COUNTER(&htim2);printf("除法时间: %lu 个时钟周期\n", end_time - start_time);printf("除法结果: %f\n", result_div);// 停止定时器HAL_TIM_Base_Stop(&htim2);
}
修改程序中i的值,进行1万次加减乘除的结果:
进行1000次加减乘除的结果:
进行100次加减乘除的结果:
进行10次加减乘除的结果:
去掉for循环,单次加减乘除的结果:
通过多次测量取平均的方法得到,单次浮点运算的时间大约不到30ns。