一、
STM32H7S78-DK内置硬件浮点运算单元,并且支持单精度、双精度浮点运算加速,其主频高达600MHz,内部含有2*32Kbytes ICache,DCache。下面来测试这款MCU的浮点计算性能
2
二、
测试方式为在MCU在未开启FPU加速与开启FPU加速下计算一百万次复数乘法所用时间,无论是嵌入式CPU还是PC端CPU,它们主要功能是取指令、译解码、数学运算,其中乘除法运算占用CPU的指令周期最多,因此一款CPU在相同时间内能够进行的乘除法次数越多,说明其性能越高。
2.1
使用CubeMX生成Keil工程,时钟树将系统时钟为600MHz,开启串口2外设用于打印输出调试信息
![1729915076796470.png S%06H9CTG[}D`8R]{KTCS{9.png](http://uphotos.eepw.com.cn/1709346044/pics/1729915076796470.png)
将STM32 L496加入这次测试,可以与STM32H7S78作性能比较
2.2 Keil工程代码、FPU开启设置
先关闭FPU加速,同时将优化等级改为O0,否则编译器仍会自动开启FPU


2.3 测试代码
声明复数结构体、复数变量
/* USER CODE BEGIN PD */
typedef struct complex1{
float real;
float imag;
}compx_float;
typedef struct complex2{
double real;
double imag;
}compx_double;
/* USER CODE END PD */
/* USER CODE BEGIN PV */
compx_float cpx1={2.3,4.3},cpx2={1.2,1.8};
compx_double cpx3={4.1,2.1},cpx4={1.3,3.1};
/* USER CODE END PV */定义浮点计算函数
/* USER CODE BEGIN 0 */
void time_consume_cpxmul_float(compx_float c1,compx_float c2,uint32_t num){
#if __FPU_USED
uint32_t start,end=0;
compx_float c;
start = HAL_GetTick();
for(uint32_t i=0;i<num;i++){ //num点复数运算
c.real=c1.real*c2.real-c1.imag*c2.imag;
c.imag=c1.real*c2.imag+c1.imag*c2.real;
}
end = HAL_GetTick();
double t = (end - start) / 1000.0f;
printf("time_consume_with_fpu=%fs\n",t);
#elif 1
uint32_t start,end=0;
compx_float c;
start = HAL_GetTick();
for(uint32_t i=0;i<num;i++){ //num点复数运算
c.real=c1.real*c2.real-c1.imag*c2.imag;
c.imag=c1.real*c2.imag+c1.imag*c2.real;
}
end = HAL_GetTick();
double t = (end - start) / 1000.0f;
printf("time_consume_no_fpu=%fs\n",t);
#endif
}
void time_consume_cpxmul_double(compx_double c1,compx_double c2,uint32_t num){
#if __FPU_USED
uint32_t start,end=0;
compx_double c;
start = HAL_GetTick();
for(uint32_t i=0;i<num;i++){ //num点复数运算
c.real=c1.real*c2.real-c1.imag*c2.imag;
c.imag=c1.real*c2.imag+c1.imag*c2.real;
}
end = HAL_GetTick();
double t = (end - start) / 1000.0f;
printf("time_consume_with_dpu=%fs\n",t);
#elif 1
uint32_t start,end=0;
compx_double c;
start = HAL_GetTick();
for(uint32_t i=0;i<num;i++){ //num点复数运算
c.real=c1.real*c2.real-c1.imag*c2.imag;
c.imag=c1.real*c2.imag+c1.imag*c2.real;
}
end = HAL_GetTick();
double t = (end - start) / 1000.0f;
printf("time_consume_no_dpu=%fs\n",t);
#endif
}
/* USER CODE END 0 */main函数运行测试
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
// HAL_Delay(300);
// printf("Hello STM32H7.\n");
// HAL_GPIO_TogglePin(USER_LD2_GPIO_Port, USER_LD2_Pin);
time_consume_cpxmul_float(cpx1,cpx2,1000000);//单精度复数乘法运算
time_consume_cpxmul_double(cpx3,cpx4,1000000);//双精度复数乘法运算
}
/* USER CODE END 3 */
}三、运行结果
3.1 未开启FPU
![1729916360563941.png RQ]7%{[GZ~LM$3MAT9GAGBO.png](http://uphotos.eepw.com.cn/1709346044/pics/1729916360563941.png)
左为STM32 H7,右为STM32 L4
相同复数乘法运算,STM32 L4耗时大约为STM32 H7的两倍
双精度运算比单精度运算耗时更长
3.2 开启单精度FPU


左为STM32 H7,右为STM32 L4
STM32 L4内置只有单精度FPU,开启FPU加速后,计算时间由4.165s减少到0.463s。双精度浮点计算时间不变
STM32 H7内置只有单精度、双精度FPU,仅开启单精度FPU加速后,计算时间由2.758s减少到0.19s。双精度浮点计算时间不变
3.3 开启双精度FPU

左为STM32 H7,右为STM32 L4
可见STM32 H7双精度FPU对单精度、双精度运算加速均有效,并且双精度加速效果比单精度加速效果好。
STM32 H7 双精度FPU加速:单精度运算时间由2.758减少至0.226s,双精度运算时间由9.332s减少至0.191s。
运算时间减少百分比分别为:91.8%、97.9%
3.4 STM32 H7S7开启I/D cache
/* MPU Configuration--------------------------------------------------------*/ MPU_Config(); /* Enable the CPU Cache */ /* Enable I-Cache---------------------------------------------------------*/ SCB_EnableICache(); //开启ICache /* Enable D-Cache---------------------------------------------------------*/ SCB_EnableDCache(); //开启DCache /* MCU Configuration--------------------------------------------------------*/
未开启FPU&开启I/D cache后

3.5
开启FPU&开启I/D cache后
![1729918533742118.png 6QQ0GH]TXG6XL~CY93K)B)F.png](http://uphotos.eepw.com.cn/1709346044/pics/1729918533742118.png)
FPU与指令数据缓存同时加速,单精度计算所需时间进一步由0.226减少至0.05s,双精度运算时间由0.191s减少至0.098s
我要赚赏金
