ZHCAEQ3 November 2024 F29H850TU , F29H859TU-Q1
在實(shí)時(shí)應(yīng)用中,飽和類(lèi)型代碼十分常見(jiàn)。以下展示了在 C 語(yǔ)言中通過(guò)兩種不同方式實(shí)現(xiàn)飽和的總結(jié)。
下面的代碼塊顯示了基于 if..else 實(shí)現(xiàn)飽和的方法。C29 需要 11 個(gè)周期且不依賴(lài)輸入,性能優(yōu)于 Cortex-M7(需要 14-27 個(gè)周期,且依賴(lài)輸入)。在 C29 上,if () 是通過(guò)條件分支指令 (BC) 實(shí)現(xiàn)的,而對(duì)于剩余的兩條路徑(elseif 和 else),則依次使用了比較指令 (CMPF) 和條件指令 (XCP),從而避免了分支。
volatile float in;
volatile float out;
const float max =1.0f;
const float min = -1.0f;
if(in > max)
out = max;
else if(in < min)
out = min;
else
out = in;
C29 Implementation
LD.32 M1,@in
||ONEF M0
CMPF TDM0,M.GT,M1,M0
ONEF M1
|| BC @($LBB0_2),TDM0.NZ
LD.32 M1,@in
|| NEGONEF M2
CMPF TDM0,M.LT,M1,M2
XCP #0x1,TDM0.Z
|| LD.32 M1,@in
SELECT TDM0,M1,M2,M1
$LBB0_2:
ST.32 @out,M1
M7 Implementation
MOVW R0,#in2
MOVT R0,#in2
MOVS R1,#+1
MOVT R1,#+16256
VLDR S0,[R0, #0]
VMOV S1,R1
VCMP.F32 S0,S1
FMSTAT
BLT.N saturation_0
MOV R2,#+1065353216
STR R2,[R0, #+4]
B saturation_2
saturation_0:
VMOV.F32 S0,#-1.0
VLDR S1,[R0, #0]
VCMP.F32 S1,S0
FMSTAT
BPL.N saturation1_1
VSTR S0,[R0, #+4]
B saturation_2
saturation_1:
LDR R1,[R0, #+0]
STR R1,[R0, #+4]
saturation_2:
下面的代碼塊顯示了基于三元運(yùn)算符 '?' 實(shí)現(xiàn)飽和的方法。C29 通過(guò) MINMAXF 指令實(shí)現(xiàn),且無(wú)需分支,需要 3 個(gè)周期且不依賴(lài)輸入,性能優(yōu)于 Cortex-M7(需要 18-22 個(gè)周期,且依賴(lài)輸入)。
volatile float in;
volatile float out;
const float max =1.0f;
const float min = -1.0f;
float temp = in;
temp = (temp > max)? max: ((temp < min)? min: temp);
out = temp;
C29 Implementation
ONEF M0 || LD.32 M1,@in || NEGONEF M2 MINMAXF M1,M0,M2 ST.32 @out,M1
M7 Implementation
MOVW R0,#in2
MOVS R1,#+1
MOVT R0,#in2
MOVT R1,#+16256
VMOV S2,R1
VLDR S0,[R0, #0]
VCMP.F32 S0,S2
VMOV.F32 S1,S0
FMSTAT
IT GE
VMOVGE.F32 S1,#1.0
BGE.N saturation_0
VMOV.F32 S2,#-1.0
VCMP.F32 S0,S2
FMSTAT
IT MI
VMOVMI.F32 S1,S2
saturation_0:
VSTR S1,[R0, #+8]
C29 編譯器經(jīng)過(guò)優(yōu)化,能夠在 if..else 或三元運(yùn)算符實(shí)現(xiàn)方式之間,生成相同性能的代碼。
|| 表示與上述指令并行執(zhí)行的指令。