Multiply-Add Instruktion ist langsam

#5817152
Lesenswert?

Ich programmiere derzeit auf dem teensy 36 Board, das hat ne ARM Cortex 
M4 CPU und bei den Fliesspunktbefehlen habe ich folgendes festgestellt:
Addition (Befehl VADD) und Multiplikation(Befehl VMUL) brauchen jweils 1 
Zyklus. Die Multiply-Add Instruction (VMLA) braucht 3 Zyklen. Damit ist 
der VMLA Befehl langsamer als wenn ich getrennt MUL und ADD mache. 
Welchen Sinn ergibt das? Welchen Vorteil hat die VMLA Instruktion?

Im folgenden Beispiel
1
 for(int k=0 ; k<nn ; k++){
2
    fx += fy * fz ;
3
    fy += 1.2 ;
4
    fz += 1.3 ;
5
    }
benutzt der GCC compiler die VMLA Instruktion für fx += fy * fz ;
#5817165
Lesenswert?

Das Ergebnis ist genauer, wenn erst abschliessend gerundet wird:
https://de.wikipedia.org/wiki/Fused_multiply-add

Es wird ein Zwischenregister eingespart.

PS: Lies auch die Fussnoten: "Floating-point arithmetic data processing 
instructions, such as add, subtract, multiply, divide, square-root, all 
forms of multiply with accumulate, as well as conversions of all types 
take one cycle longer if their result is consumed by the following 
instruction."
  FMUL
  FADD
  ..use result..
hat 2 Straftakte drin und kommt damit auf 4 Takte, während
  VMLA
  ..use result..
nur einen Straftakt hat und damit gleichauf liegt.
#5817377
Lesenswert?

Das klingt schon mal logisch. Besten Dank.

Ich habe die Reihenfolge der Statements in der Schleife jetzt mal 
geändert (siehe unten). Ich dachte ich könnte so einen Strafzyklus 
notwendig machen, weil der vfma Befehl jetzt das Resultat des vadd 
Befehls vor ihm braucht. Aber der Compiler hat geschickterweise die subs 
Instruktion vorgezogen.
1
  int32_t start=micros() ;
2
  for(int k=0 ; k<nn ; k++){ 
3
    fy += 1.2 ;
4
    fz += 1.3 ;
5
    fx += fy * fz ;
6
    }
7
  int32_t stop=micros() ;
8
/*
9
   50e: ee37 7a06   vadd.f32  s14, s14, s12    1 Zyklus
10
   512: ee77 7aa5   vadd.f32  s15, s15, s11    1 Zyklus
11
   516: 3b01        subs  r3, #1               1 Zyklus
12
   518: eee7 6a27   vfma.f32  s13, s14, s15    3 Zyklen
13
   51c: d1f7        bne.n 50e <setup+0x9e>     2 Zyklen
14
*/

Jetzt verstehe ich folgendes nicht: Meine Laufzeitmessung sagt, dass ein 
Schleifendurchlauf 7 Zyklen braucht. Ich komme aber auf 8 Zyklen, wo 
mache ich einen Fehler ?
#5817403
Lesenswert?

void schrieb:
> Wilde Vermutung: bne.n hat unterschiedliche Ausführungszeit für branch
> taken und branch not taken

Die hat er mit 2 Takten schon eingerechnet. Aber ohne nun beim M4 
konkret nachgesehen zu haben könnte es sein, dass das Gesamtsystem ihm 
noch einen Takt für nichtsequentiellen Zugriff oder schlecht aligntes 
Sprungziel zusätzlich drauf haut.
#5817540
Lesenswert?

Die Pipeline widmet sich bereits dem Sprungbefehl und dessen Ziel, 
während der VMLA Befehl noch läuft. Das ist zwar spekulativ, aber 
dadurch reduziert sich die Laufzeit der Execute-Stage des Sprungbefehls 
auf einen Takt zur Bestätigung.

https://community.arm.com/developer/ip-products/processors/f/cortex-m-forum/8969/question-about-the-pipeline-clock-cycle-and-machine-cycle-in-cortex-m-series
Gast #5817685
Lesenswert?

Martin O. schrieb:
> Welchen Sinn ergibt das? Welchen Vorteil hat die VMLA Instruktion?

Normalerweise macht man damit Filter und optimiert selbige.

Das heißt - da man ohnehin beim Filtern 2 Datenströme bearbeiten muß (I 
und Q) - kann man das Ganze auch verschachteln und die Schleife zum Teil 
aufrollen, womit man den Taktverbrauch für das Schleifenzählen und 
Springen reduziert.

Also mal ganz grobschlächtig skizziert so:
 for ..
{ sumI = sumI + pkoeffI++ * psamplI++;
  sumQ = sumQ + pkoeffQ++ * psamplQ++;
  sumI = sumI + pkoeffI++ * psamplI++;
  sumQ = sumQ + pkoeffQ++ * psamplQ++;
  ...usw. immer I und Q abwechselnd
}
Wenn man z.B. in der Schleife 8 solche IQ Paare drin hat, dann ist der 
Aufwand in Takten für das Schleifenzählen nur noch 1/8 dessen, was man 
mit nur einem Paar braucht.

W.S.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren