int16 FIX_MPY(int16 a, int16 b)
{
// shift right one less bit
int32 c = ((int32)a * (int32)b) >> 14;
// last bit shifted out = rounding-bit
b = c & 0x01;
// last shift + rounding bit
a = (c >> 1) + b;
return a;
}
Gibts da Optimierungspotential? Die Routine wird sehr oft (16384 mal pro
Berechnung) aufgerufen, wenn man da noch was machen könnte, ich bin in
Zeitnot :-)
Ist für einen M16, und auf die Rundung kann ich nicht verzichten.
Ich sehe nichts mehr.
Hallo, du könntest die Multiplikation vom HW-Multiplizierer ausführen lassen. Normalerweise sollte sich unter den intrinsics was finden lassen. Dann würde ich wahrscheinlich zwei mal nach links schieben und das Hiword nehmen. Mir ist z.B. beim IAR Compiler mal aufgefallen, dass der Compiler wirklich 14 mal schiebt in solchen Fällen (hängt wahrscheinlich von der Optimierungsstufe ab). Zwei mal schieben und dann ein mov.w ist da schon etwas schneller. Kannst Du die Funktion evtl. als inline Funktion verwenden? Viele Grüße, Ralf
;## # FUNCTION FIX_MPY
;## # FRAME AUTO ( __PAD11) size 1, offset -1
;## # REGISTER ARG ( a) size 2, REGISTER R1
;## # REGISTER ARG ( b) size 2, REGISTER R2
;## # ARG Size(0) Auto Size(1) Context Size(5)
._type 307,'x',269,2
._type 307,'m','a',0,269
._type 307,'m','b',0,269
._func 'FIX_MPY','G',1,307,$FIX_MPY,0
._inspect 'F', 's', "FIX_MPY", "$FIX_MPY", 'G', 6
.align
._line 303
;## # C_SRC : {
.glb $FIX_MPY
$FIX_MPY:
enter #01H
._block
._var 'a','A',269,0
._var 'b','A',269,0
._var 'c','A',292,0
._line 305
;## # C_SRC : int32 c = ((int32)a * (int32)b) >> 14;
._block
._var 'a','R',269,6
._var 'b','R',269,7
mul.w R2,R1 ; b
._eblock
sha.l #-8H,R3R1
sha.l #-6,R3R1
._line 307
;## # C_SRC : b = c & 0x01;
mov.w R1,R0
and.w #0001H,R0 ; b
._block
._var 'b','R',269,5
._line 309
;## # C_SRC : a = (c >> 1) + b;
sha.l #-1,R3R1
add.w R1,R0 ; a
._eblock
._block
._var 'a','R',269,5
._line 312
;## # C_SRC : return a;
._eblock
exitd
das der Auszug aus dem listing. Scheint genauso gemacht, wie du
vorgeschlagen hast, schade.
Trotzdem vielen Dank.
What is the exact purpose of your code? Knowing that can help to
optimise.
By shifting right by 14 places, you are throwing away a lot of
information. Maybe you can find a way to figure out how to not calculate
those bits in the first place. As far as I understand, even many
hardware multipliers have a variable execution time that increases with
the number of non-zero bits.
The following code is a little simpler and should be equivalent to
yours:
int16 FIX_MPY(int16 a, int16 b)
{
// shift right one less bit
int32 c = ((int32)a * (int32)b) >> 14;
// round it
return ((c + 1) >> 1);
}
Thanks for the idea!
int16 FIX_MPY(int16 a, int16 b)
{
int32 c = ((int32)a * (int32)b + (1<<14)) >> 15;
return c;
}
Irgendwie geht immer noch was :-)
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.