FFT Benchmark auf einem STM32F4 Microcontroller, Beagle Bone Black und PC

01/12/2013 - 20:09 von Frank Buss | Report spam
Da ich demnàchst eine FFT für ein Projekt für den Beagle Bone brauche,
und letztens die Frage aufkam, habe ich mal die Kiss FFT Library auch
für mein STM3F4Discovery Devboard ausprobiert. Hier die Library:

http://kissfft.sourceforge.net

(KISS ist Programmiererslang und bedeutet soviel wie das Gegenteil von
Feature Creep, was man bei anderen FFT-Libraries gerne sieht:
http://de.wikipedia.org/wiki/KISS-Prinzip )

Hier das gesamte Testprojekt:

http://www.frank-buss.de/tmp/FFT-Test.zip

Ist recht groß, da ich das gesamte Projekt mal zusammengepackt habe,
hier der relevante Sourcecode für den Test:

http://pastebin.com/0tPbWJjW

Ich habe es mit cs-make von CodeSourcery compiliert, mit einem GCC
4.6.1. Im Hintergrund habe ich noch zwei I2S Datentransfers per DMA
laufen lassen, mit 96 kHz Samplefrequenz und 32 Bit Wortbreite, Daten
gesendet und empfangen, im Full-Duplex und Double-Buffering Betrieb, mit
zusàtzlicher Zwischenspeicherung und Lesen aus einem Ringbuffer. Das
macht aber nicht viel aus, ohne Transfer làuft es nur ca. 6% schneller.

Hier die Messergebnisse pro FFT-Berechnung, wenn der ARM-Core mit der
maximalen Geschwindigkeit von 168 MHz làuft:

size: 256, time: 0.257400 ms, with dB: no, sum: 12798979072.000000
size: 256, time: 3.709400 ms, with dB: yes, sum: 252872096.000000
size: 512, time: 0.698600 ms, with dB: no, sum: 25597667328.000000
size: 512, time: 7.601900 ms, with dB: yes, sum: 526377920.000000
size: 1024, time: 1.164700 ms, with dB: no, sum: 51200745472.000000
size: 1024, time: 14.972600 ms, with dB: yes, sum: 1180834944.000000
size: 2048, time: 3.057900 ms, with dB: no, sum: 102385901568.000000
size: 2048, time: 30.673901 ms, with dB: yes, sum: 2318690560.000000

Ich habe einmal nur die FFT berechnen lassen und die Ergebnisse summiert
(damit eine eventuelle Optimierung das nicht wegoptimiert), was die
Angabe "with dB: no" ist. Ein etwas praxisrevelanteres Beispiel ist
dann, "10 * log10f(r * r + i * i)" auf jedem Ergebniswert zu berechnen.
Das scheint die Zeit ziemlich zu erhöhen.

Eigentlich hat der verwendete ARM eine Floating-Point Einheit, aber die
hat glaube ich keine transzendente oder logarithmischen Funktionen. Also
wenn man schnell bleiben will, sollte man in der quadratischen Ebene die
Daten weiterverarbeiten, oder ggf. eine schnellere Nàherung für den
Logarithmus verwenden. Sieht aber generell recht gut aus, wenn man
irgendwas realtime-màßiges damit machen wollte. Ich will demnàchst mal
den FFT-Overlap-Add Algorithmus damit ausprobieren, da man damit lange
FIR-Filter sehr schnell in der Frequenzdomàne berechnen kann und dann in
Echtzeit Audiosignale damit bearbeiten.

Hier die Ergebnisse von einem Beagle Bone Black, mit dem darauf
installierten Compiler compiliert (und leicht modifiziertem Testcode mit
dem Qt-Framework für die Zeitmessung, da ich das für die eigentliche
Anwendung spàter auch brauche), der mit 1 GHz làuft:

size: 256, time: 0.440500 ms, with dB: no, sum: 12798979072.000000
size: 256, time: 0.590400 ms, with dB: yes, sum: 252872096.000000
size: 512, time: 0.955500 ms, with dB: no, sum: 25597667328.000000
size: 512, time: 1.300000 ms, with dB: yes, sum: 526377920.000000
size: 1024, time: 2.060500 ms, with dB: no, sum: 51200745472.000000
size: 1024, time: 2.743500 ms, with dB: yes, sum: 1180834944.000000
size: 2048, time: 4.627700 ms, with dB: no, sum: 102385901568.000000
size: 2048, time: 5.991300 ms, with dB: yes, sum: 2318690560.000000

Interessanterweise langsamer, als auf dem STM3F4, aber der Logarithmus
làuft merkwürdigerweise bedeutend schneller. Ist bei der CodeSourcery
Library etwa die Mathematik-Library ohne die Floating-Point-Einheit
compiliert worden und auf dem Beagle Bone Black alles nur per Software
Emulation berechnet? Bin jetzt zu faul nachzuschauen, ob der eine
Hardware Floating-Point-Einheit hat, wie es der ARM Core auf dem
Raspberry Pi bietet und mit dem "hardfp" Debian Wheezy.

Und schließlich zum Vergleich die Messung mit dem gcc von mingw von Qt
Creator im Release-Modus für Windows compiliert, ausgeführt auf einem
Intel Xeon mit 2,4 GHz Takt:

size: 256, time: 0.008000 ms, with dB: no, sum: 12798615552.000000
size: 256, time: 0.014900 ms, with dB: yes, sum: 252872080.000000
size: 512, time: 0.019200 ms, with dB: no, sum: 25597716480.000000
size: 512, time: 0.034500 ms, with dB: yes, sum: 526377888.000000
size: 1024, time: 0.033800 ms, with dB: no, sum: 51195023360.000000
size: 1024, time: 0.064900 ms, with dB: yes, sum: 1180834944.000000
size: 2048, time: 0.085000 ms, with dB: no, sum: 102391111680.000000
size: 2048, time: 0.147700 ms, with dB: yes, sum: 2318690560.000000

Ist also 40 bis 250 mal (für die log10-Berechnung) schneller, als auf
dem STM32F4. Man sieht auch kleinere Unterschiede in der Summe, obwohl
alle ja eigentlich floats mit 4 Bytes verwenden, was vielleicht daran
liegt, daß der Intel intern mit höherer Genauigkeit rechnet.

Den I2S Datentransfer mit DMA Transfer zu programmieren war übrigens
nicht so einfach, da es kein genau passendes Beispiel für meinen
Anwendungsfall gab (ich wollte einen externen Chip per
I2S3/I2S3Ext-Modul ansprechen). Ich dachte bin ich vielleicht in 1-2
Stunden fertig, aber war dann 350 Zeilen und zwei Tage spàter froh, daß
es endlich làuft. Eine falsche Zeile und nichts làuft mehr, was die
Fehlersuche interessant macht.

Die STM32 Library ist auch zu low-level, sodaß man leicht Fehler machen
kann oder was vergessen kann (DMA_IT_TCIF5 statt DMA_FLAG_TCIF5 für den
DMA_ClearITPendingBit-Aufruf verwendet? Interrupt-Sturm). Und das
Datenblatt ist nicht immer genau: Reference-Manual sagt "examples of DMA
request mappings", "depends on the product implementation", aber man
findet es nicht im Datasheet des betreffenden Prozessors. Und es stellte
sich heraus, daß es nicht nur ein Beispiel ist, sondern daß es anders
als dort angegeben erst gar nicht làuft. Wieder ein paar Stunden weg mit
Fehlersuche.

Mir sind auch noch ein paar Sachen etwas unklar, vielleicht werde ich
mal den Support anschreiben. Aber letztens meinte jemand, daß der gar
nicht erst antwortet. Schade, denn der Microcontroller ist wirklich gut,
was ich bis jetzt so gesehen habe und ich konnte auch noch keinen
Chip-Fehler bei meinen Experimenten feststellen, wie man es schonmal bei
manchen Chips von Atmel hat. Fehlt nur noch eine einfacherere
anzuwendende Library, wenn man nicht die Register alle selbst
programmieren will.

Oder noch besser: ein GUI mit Codegenerator, wie es die PSoC IDE von
Cypress bietet. Da kann man schon von vorneherein keine Fehler bei der
Registerkonfiguration machen, da das GUI jeweils nur die gültigen
Auswahlmöglichkeiten zur Verfügung stellt. Ich bin ja eigentlich nicht
ein Fan von Codegeneratoren, aber die machen einem das
Programmiererleben wirklich leichter.

Frank Buss, http://www.frank-buss.de
electronics and more: http://www.youtube.com/user/frankbuss
 

Lesen sie die antworten

#1 Olaf Kaluza
01/12/2013 - 20:50 | Warnen spam
Frank Buss wrote:

und letztens die Frage aufkam, habe ich mal die Kiss FFT Library auch
für mein STM3F4Discovery Devboard ausprobiert. Hier die Library:



Interessant. Ich hab leider gerade etwas wenig Zeit sonst haette ich
es mal mit meinem SH2A verglichen.

Ich habe es mit cs-make von CodeSourcery compiliert, mit einem GCC
4.6.1. Im Hintergrund habe ich noch zwei I2S Datentransfers per DMA



Wenn du Vergleiche zulassen willst dann musst du die ganzen aktiven
Compilerswitches mit angeben.

Den I2S Datentransfer mit DMA Transfer zu programmieren war übrigens


[..]
es endlich làuft. Eine falsche Zeile und nichts làuft mehr, was die
Fehlersuche interessant macht.



Was mich an der DMA-Sache beim SH2A immer fasziniert hat, man kann
irgendeinen Fehler machen der die CPU total abstuerzt, aber er spielt
dann die letzten 5-10s meiner Musik aus dem Ram einfach weiter. Selbst
wenn man das Programm im Debugger anhaelt.


Mir sind auch noch ein paar Sachen etwas unklar, vielleicht werde ich
mal den Support anschreiben. Aber letztens meinte jemand, daß der gar
nicht erst antwortet.



Antworten tun sie schon, sie brauchen nur viele Tage bis Wochen und
haben bei mir keinen besonders kompetenten Eindruck hinterlassen. Und
dabei habe ich den Vorteil auf meiner Visitenkarte einen Firmennamen
stehen zu haben der die Verkaeufertypen normalerweise sehr
befluegelt. Als ein Kollege letztens bei TI angerufen hat, da hat es
drei Tage gedauert und zwei Ings von denen standen in der Tuer um uns
zu erklaeren wie man deren Problem umgehen kann. :)


Schade, denn der Microcontroller ist wirklich gut,
was ich bis jetzt so gesehen habe und ich konnte auch noch keinen
Chip-Fehler bei meinen Experimenten feststellen, wie man es schonmal bei
manchen Chips von Atmel hat.



Mit dem F4 habe ich selber auch nur ein bisschen privat
rumgespielt. Dafuer habe ich einiges mit dem STM32L1 gemacht das jetzt
in Stueckzahlen laeuft. Da habe ich schon einen Bug gefunden.

Fehlt nur noch eine einfacherere
anzuwendende Library, wenn man nicht die Register alle selbst
programmieren will.



Ich mag soetwas nicht so besonders. Schon garnicht wenn Fehler drin
sind und der Hersteller zu faul ist ein Datenblatt fuer jede CPU zu
schreiben, es also nur ein gemeinsames Datenblatt fuer alle Modelle
gibt. So koennen z.B nicht alles Zaehler im L1 als Up und Downcounter
arbeiten. Die Libary akzeptiert es aber das man das Richtungsbit auch
bei einem Zaehler setzt der es nicht kann.


Oder noch besser: ein GUI mit Codegenerator, wie es die PSoC IDE von
Cypress bietet. Da kann man schon von vorneherein keine Fehler bei der
Registerkonfiguration machen, da das GUI jeweils nur die gültigen
Auswahlmöglichkeiten zur Verfügung stellt. Ich bin ja eigentlich nicht
ein Fan von Codegeneratoren, aber die machen einem das
Programmiererleben wirklich leichter.



Solche Libary machen einem die ARbeit zuerst ein bisschen einfacher,
aber sie kosten hinterher das doppelte der gesparten Zeit wenn man
merkwuerdige Fehler suchen muss.

Du kannst dir ja mal die Geckos anschauen. Da gibt es wohl soetwas
auch. Liess dir aber vorher die Erratas durch und stelle fest das die
teilweise jeden Monat eine neue Liste rausbringen.

Olaf

Ähnliche fragen