這幾天剛拿到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 ED900A00 VLDR s0,[r0,#0x00]
0x08000224 4804 LDR r0,[pc,#16] ; @0x08000238
0x08000226 EDD00A00 VLDR s1,[r0,#0x00]
0x0800022A EE801A20 VDIV.F32 s2,s0,s1
0x0800022E 4803 LDR r0,[pc,#12] ; @0x0800023C
0x08000230 ED801A00 VSTR s2,[r0,#0x00]
復制代碼 F28335: F28335的FPU有加減乘法指令,都是雙周期的,由於沒有硬件除法指令,F28335這裏是用軟件模擬的浮點除法,匯編可以看到 LCR $div_f32.asm字樣,需要19個時鐘周期。
例如:a = a * b,產生的匯編為:
0087B2 E203 MOV32 *-SP[4], R0H
0087B4 E2AF MOV32 R1H, *-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 MOV32 R1H, *-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的數學庫中,各自支持的運算種類不壹樣。