![](https://img.51dongshi.com/20241130/wz/18296974952.jpg)
論壇上看到的比較。 這幾天剛拿到STM32F4的評估板,STM32F4這次的賣點就是FPU和DSP指令集,關注了挺長時間,這次就想測試一下STM32F4的浮點性能,如果滿足就升級自己飛控的架構。本來用STM32F103+28335雙核架構,F28335當浮點處理器用,調試起來比較麻煩,所以一直想換了。 測試代碼就是用的我飛控的算法,全部使用浮點運算,包含姿態和位置兩個7階和9階的卡爾曼濾波器,包含大量的矩陣運算以及部分導航算法和PID控制器等,還有部分IF和SWITCH包含跳轉的判定語句,相比純算法算是一個比較綜合的運算。 測試環境: F28335:CCS V3.3,使用TI優化的數學庫,不開優化,程序在RAM里執行。 STM32F4:KEIL V4.7,使用ARM優化的數學庫,不開優化。 測試方法: F28335:在飛控算法入口設置斷點,清零CCS的CPU計數器(profile->clock),然后STEP OVER,記錄下CPU的計數 STM32F4:在飛控算法入口設置斷點,記錄下Register窗口內算states計數器,然后STEP OVER,記錄下新的計數器數值,與之前的數值相減得到CPU計數 測試結果: F28335:253359個CPU周期,除以150MHZ,大約是1.69ms STM32F4:一共285964個周期,除以168MHZ,大約是1.7ms,比F28335略慢 結論就是,對于包含相對較多跳轉的綜合浮點算法而言,STM32F4似乎并不慢多少。 拋開架構因素,從純浮點運算方面來看的話。STM32F4的FPU加減乘指令VADD.F32、VSUB.F32、VMUL.F32都是單周期指令,而除法VDIV.F32耗費14個周期。 例如:a = a / b;產生的匯編為: 0x08000220 ED900A00VLDRs0,[r0,#0x00] 0x08000224 4804LDR r0,[pc,#16]; @0x08000238 0x08000226 EDD00A00VLDR s1,[r0,#0x00] 0x0800022A EE801A20VDIV.F32s2,s0,s1 0x0800022E 4803LDR r0,[pc,#12]; @0x0800023C 0x08000230 ED801A00VSTR s2,[r0,#0x00] 復制代碼 F28335:F28335的FPU有加減乘法指令,都是雙周期的,由于沒有硬件除法指令,F28335這里是用軟件模擬的浮點除法,匯編可以看到 LCR$div_f32.asm字樣,需要19個時鐘周期。 例如:a = a * b,產生的匯編為: 0087B2 E203 MOV32*-SP[4], R0H 0087B4 E2AF MOV32R1H, *-SP[6], UNCF 0087B6 E700 MPYF32 R0H, R1H, R0H 0087B8 7700 NOP //需要讓流水線等待FPU運算完畢,所以需要NOP 0087B9 E203 MOV32*-SP[4], R0H 復制代碼 除法: 0087BD E203 MOV32*-SP[4], R0H 0087BF E2AF MOV32R1H, *-SP[6], UNCF 0087C1 7640 LCR$div_f32.asm:52:71$ 0087C3 E203 MOV32*-SP[4], R0H 復制代碼 結論: 可見單從浮點處理器來說,F28335是不如F4的FPU的。但是由于F28335是哈佛架構,有較長的流水線,可以在一個時鐘周期里完成讀取,運算和存儲,所以程序連續運行的話,就比ARM快上許多許多,比如執行一次a = a + b只需要5個時鐘周期,但是缺點就是一旦要跳轉,就必須清空流水線,如果是 for(i = 0;i < 1000; i ++) a = a + b; 復制代碼 這樣的運算,速度反而要比ARM慢(測試下來單次是17周期,ARM是14).所以說這就是ARM和DSP不同的地方了。 看看這次測試比較,感覺環境還是有一定的問題: 1、F28335是在RAM中運行,并且兩者都是在仿真器環境中進行運算,還是離線在Flash中跑比較靠譜。 2、兩者編譯平臺一個是CCS,一個是KEIL,對通用語句的優化,有待商榷。 3、ARM和TI的數學庫中,各自支持的運算種類不一樣。