一、
STM32H7S78-DK内置硬件浮点运算单元,并且支持单精度、双精度浮点运算加速,其主频高达600MHz,内部含有2*32Kbytes ICache,DCache。下面来测试这款MCU的浮点计算性能
2
二、
测试方式为在MCU在未开启FPU加速与开启FPU加速下计算一百万次复数乘法所用时间,无论是嵌入式CPU还是PC端CPU,它们主要功能是取指令、译解码、数学运算,其中乘除法运算占用CPU的指令周期最多,因此一款CPU在相同时间内能够进行的乘除法次数越多,说明其性能越高。
2.1
使用CubeMX生成Keil工程,时钟树将系统时钟为600MHz,开启串口2外设用于打印输出调试信息
将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
左为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后
FPU与指令数据缓存同时加速,单精度计算所需时间进一步由0.226减少至0.05s,双精度运算时间由0.191s减少至0.098s