VDSP 未直接提供 fract16 除法函數,文檔給出範例演算法:將分子擴展為 32-bit,使用 divs/divq 迭代 15 次產生商。但原版未處理符號,導致異號除法錯誤。
fract16 saturating_fract_divide(fract16 nom, fract16 denom) {
int partialres = (int)nom;
int divisor = (int)denom;
if (partialres == 0) return 0;
else if (partialres >= divisor) return 0x7FFF; // 符號錯誤
partialres <<= 16;
partialres = divs(partialres, divisor, &aq);
for (int i=0; i<15; i++) partialres = divq(partialres, divisor, &aq);
return (fract16)partialres;
}
未優化 500 cycles,優化後 42 cycles。
fract16 saturating_fract_divide(fract16 nom, fract16 denom) {
int sign = (nom ^ denom) & 0x8000;
int partialres = abs_fr1x16(nom);
int divisor = abs_fr1x16(denom);
if (partialres == 0) return 0;
else if (partialres >= divisor) return 0x7FFF;
partialres <<= 16;
partialres = divs(partialres, divisor, &aq);
for (int i=0; i<15; i++) partialres = divq(partialres, divisor, &aq);
fract16 rtn = (fract16)partialres;
if (sign) rtn = negate_fr1x16(rtn);
return rtn;
}
優化前 522 cycles,優化後 50 cycles。關鍵點:先取絕對值運算,最後依符號位決定是否取反。