Forum: Mikrocontroller und Digitale Elektronik Cortex M4 und FPU Performance


von Mampf F. (mampf) Benutzerseite


Lesenswert?

Guten Morgen,

ich versuche gerade einen Audio-Dynamic-Compressor auf einen Cortex M4 
(STM32F429) zu portieren, den ich mal von Lisp (Chris Dynamic Compressor 
als Audacity-Plugin) nach C und dann nach VHDL portiert hatte.

Für den Port nach VHDL hatte ich alles auf Festpunktarithmetik 
umgestellt und Funktionen wie die Umrechnung von linear->db, db->linear, 
1/x und sqrt(x) so implementiert, dass ich in VHDL keine 
Fließkomma-Arithmetik benötige.

Nun hab ich festgestellt, dass die Cortex M4 eine FPU eingebaut haben 
und der Compiler float gut nutzen kann ...

Die meisten Verfahren sind iterativ und brauchen deshalb vermutlich mehr 
CPU-Zyklen, als wenn die FPU direkt verwendet werden würde (?).

Zum Vergleich:
1
float Lin2Db::conv(int data) {
2
  int j=15;
3
  int bm=0x8000;
4
5
  while (!(data & bm) && bm)
6
  {
7
    j--;
8
    bm>>=1;
9
  }
10
  // zero input = -1000.0f db output
11
  if (!bm)
12
    return -1000.0f;
13
  int e = max(j-7,0);
14
  int idx = data >> e;
15
16
  return m_lutman->data[idx]+m_lutexp->data[e]-m_k2;
17
}

wäre das Gleiche wie:
1
float ret=(20.0f*log((float)data/32767.0f)/log(10.0f));

Hat jemand eine Idee, wie performant ln(x), 1/x, e(x) und sqrt(x) auf 
einem Cortex mit FPU arbeitet verglichen mit Implementierungen, die nur 
Festpunkt-Arithmetik benutzen?

Viele Grüße,
Mampf

von Mampf F. (mampf) Benutzerseite


Lesenswert?

Ah erste Infos aus einem PDF von ST:
1
VABS.F32 Absolute value 1
2
VADD.F32 Addition 1
3
VSUB.F32 Subtraction 1
4
VMUL.F32 Multiply 1
5
VDIV.F32 Division 14
6
VCVT.F32 Conversion to/from
7
integer/fixed-point 1
8
VSQRT.F32 Square root 14

SQRT und DIV brauchen 14 Zyklen ... Ist aber immer noch schneller als 
iterativ die Wurzel zu bilden ...

Beispielsweise meine 1/x Funktion:
1
float Recip::conv(float in) {
2
  int data = (int) (in*65536.f);  
3
  int dtmp = data;
4
  if (!data)
5
    throw std::string("div by 0!");
6
7
  int j=15;
8
  while (true) {
9
    if (dtmp & 0x8000) {
10
      break;
11
    }
12
    j--;
13
    dtmp<<=1;
14
  }
15
  int e = max(j-7,0);
16
  int idx = data >> e;
17
  return m_lutman->data[idx] * pow(2,-e);
18
}


Mmhmmmm ... Glaub, ich muss es einfach mal messen ...

von Alex E. (tecnologic) Benutzerseite


Lesenswert?

Moin,

messen ist auf jeden Fall gut. Denke aber auch daran was für eine FPU du 
hast. Die des M4 ist immer eine single precision. Deshalb solltest du 
beim GCC -fsingle-constant übergeben. Dann werden auch die math.h 
Funktionen mit float anstelle von double (in software) gerechnet. Ob 
deine Rechnung dann nummerisch instabil wird weil die Genauigkeit des 
Floats nicht aus reicht musst du aus probieren.

Ansonsten sieh dir die CMSIS DSP Lib an. Die Implemtierungen sind ggf. 
schneller als math.h.

Gruß

Tec

von Mampf F. (mampf) Benutzerseite


Lesenswert?

Tec N. schrieb:
> Die des M4 ist immer eine single precision. Deshalb solltest du
> beim GCC -fsingle-constant übergeben. Dann werden auch die math.h
> Funktionen mit float anstelle von double (in software) gerechnet. Ob
> deine Rechnung dann nummerisch instabil wird weil die Genauigkeit des
> Floats nicht aus reicht musst du aus probieren.
>
> Ansonsten sieh dir die CMSIS DSP Lib an. Die Implemtierungen sind ggf.
> schneller als math.h.

Vielen Dank für die guten Tipps! :)

von Mampf F. (mampf) Benutzerseite


Lesenswert?

Also ich hab es jetzt so gemacht ... Zurück auf Float umgebaut und die 
Standard-Math-Funktionen verwendet.

Haut einwandfrei hin und ich glaube der Controller langweilt sich 
trotzdem fast nur - trotz MP3-Decoder^^

168MHz ist schon eine Menge Holz, wenn sonst kein OS darauf läuft :)

Netterweise braucht dieser Dynamik-Kompressor sowiso kaum CPU-Zeit, da 
das Audio noch auf ca 30Hz runtergerechnet wird ... Allerdings macht er 
einen Lookahead von bis zu 30 Sekunden und die 30 Sekunden Audio-Samples 
muss man zwischen speichern, weshalb man ein Haufen RAM braucht xD

Der Compressor ist aber sehr geil und ich denke, die Arbeit hat sich 
gelohnt :)

: Bearbeitet durch User
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
Noch kein Account? Hier anmelden.