Hey, mir ist aufgefallen, dass unter DAVE für die Cortex M4 der
Speicherplatzverbrauch ganz schön in die Höhe schießt, sobald ich eine
Funktion aus der ARM-DSP-LIB verwende, z.B. arm_cos_f32(). Das sind dann
mal eben 170KB(!!) mehr, die an Flash gebraucht werden. Mit Optimierung
-s ändert sich nicht viel, knapp 2k. Wie schaut das bei ST- oder
NXP-M4-Controllern aus wenn ihr die DSP-LIB verwendet?
Leon
float32_t arm_cos_f32 (float32_t x)
Stinkt ganz gewaltig danach, das du die FPU nicht aktiviert hast und
damit das ganze Software-Floatingpoint Zeugs mit in den Code bekommen
hast?
Hast du die Optimierung im Quellcode aktiviert? Sind eventuell
Debugging-Symbole darin (was gegen ersteres sprechen würde)
bvf schrieb:> Hast du die Optimierung im Quellcode aktiviert? Sind eventuell> Debugging-Symbole darin (was gegen ersteres sprechen würde)
Meine natürlich: hast du die Optimierung im Compiler aktiviert? (z.B.
wie -O1, -O2, -O3 beim GCC. Weiß nicht ob das beim DAVE auch so heißt).
Die FPU ist aktiviert, dafür spricht auch die Performance.
Die Optimierung ist über die Projektoptinen eingeschaltet, im
Konsolenfenster ist zu sehen, dass u.a. "-s" an den gcc übergeben wird,
damit werden ca. 2kB eingespart, nicht viel gemessen an der Gesamtgröße.
Standardeinstellung Debugging ist "g3" (max. Debugging-Level), wenn ich
das abschalte, ändert sich nichts an der Codegröße.
Ich habe das Gefühl, dass der GCC an der DSP-LIB nichts optimiert.
Bei solchen Problemen sollte man immer mal in die Disassembly schauen.
Allein zu sehen, welche Funktionen dort landen und wie sie sich aufrufen
spricht oft schon Bände. Damit kann man viel mehr anfangen als nur mit
der Größe des Images...
bvf schrieb:> Weiß nicht ob das beim DAVE auch so heißt
IMHO basiert DAVE auf Eclipse und dem GCC. Verwende mal für die
Compileraufrufe:
-mcpu=cortex-m4 -mfpu=fpv4-sp-d16 -mfloat-abi=hard -mthumb
-ffunction-sections -fdata-sections -Os -flto
Genaueres hier: http://www.mikrocontroller.net/articles/ARM_GCC
-mfloat-abi=hard wird nicht unterstützt, Standard ist eine softfp, wobei
laut Infineon Forum dies nur bedeutet, dass die FPU-Register nicht zur
Parameterübergabe verwendet werden, die FPU aber genutzt wird. Unter
Dave gibt es drei Einstellungen: Eine die die FPU abschaltet und
softwaremäßig emuliert, eine "Software supported FPU" (Standard) und die
Option "Hard" (bei mir nicht compilierbar).
Die FPU ist aktiviert, zum einen ist das Flag "__FPU_Present" präsent
und die Bits CP10 und 11 werden in der Init-Routine gesetzt (habs extra
nochmal mit nem Breakpoint geprüft).
Ich werde morgen noch etwas anderes ausprobieren:
Bisher linke ich nicht die arm_cortexM4_mathL_1 & 2 sondern die
arm_cortexM4bf_math, wie in der CMSIS-Beschreibung.
Wenn der Code größer ist als erwartet schaue ich zuerst in das Mapfile.
Vielleicht ist es einfach eine große Lookup Tabelle. ARM dürfte sich
nicht sonderlich um Flash kümmern solange nur die Benchmarks gute
Ergebnisse liefern.
Ich muß allerdings zu meiner Schande gestehen dass ich es bislang noch
nicht geschafft habe etwas mit der DSP-Lib zu machen. So wie es aussieht
bin ich da aber keine Ausnahme. Denn ansonsten wäre der Fall vermutlich
schon geklärt.
ich habe ein Testprojekt mit einem M3 LPC1769 und DSPlib und nutze FFT
Funktionen aus der Lib, also mit Software floats ist das komplette
binary noch <60 kB. Die sin/cos 'kosten' so je 1,5 kB weil das aus
Tabelle/Algorithmus berechnet wird.
Vielleicht also eher in Richtung Linkerschalter suchen?
komischer Effekt den ich dabei gesehen habe: In meinem Projekt waren die
'link time optimization' disabled, durch einschalten wurde der Code +7kB
grösser.
Mit dem 'hard' und 'soft' eabi habe ich mich schon mal rumgeärgert, da
müssen alle objectfiles und libs mit der gleichen Option übersetzt
worden sein. Die Info steht aber in den libs drin und der linker meckert
wenn das nicht passt.
gcc schrieb:> -ffunction-sections
und beim Linken das dazu passende Gegenstück -Wl,--gc-sections nicht
vergessen!
Und testweise auch mal beides (Kompilieren und Linken) mit -flto
probieren, das holt evtl auch noch ganz schön was raus.
Stefan schrieb:> Ich muß allerdings zu meiner Schande gestehen dass ich es bislang noch> nicht geschafft habe etwas mit der DSP-Lib zu machen. So wie es aussieht> bin ich da aber keine Ausnahme.
Unter Dave ist das recht einfach:
Du musst "__FPU_Present" und "CORTEX_M4_H" definieren, die beiden
"arm_mathxx_x" (alternativ "arm_cortexM4xf_math") sowie "m" in den
Linkereinstellungen eintragen und das Verzeichnis angeben, wo die
DSP-Libs zu finden sind. Die sind bei DAVE zwar mit dabei, das
Verzeichnis ist aber standardmäßig nicht eingetragen.
(Ich habe den Computer mit DAVE nicht vor mir, daher können genannten
Einstellungen falsch geschrieben sein!)
@Jojo: Könntest du mal eine 1024-Punkte-f32-CFFT laufen lassen? Bei mir
hat die auf einem XMC4500 soweit ich mich erinnere knapp 125000 cycles
benötigt. Die Anzahl an cycles sieht für meinen Geschmack recht
optimiert aus; eine Radix2-1024-Punkte-FFT benötigt theoretisch 10240
(N*LOG2(N)) komplexe Rechenoperationen.
Der Testdatensatz war eine Sinusschwingung mit genau 8 Perioden im
Eingangspuffer.
Leon
der Debugger zickt, habe den LPCXpresso 1759 bisher immer mit dem
LPC-Link programmiert. Dann einige Updates der IDE installiert, die ist
jetzt ein Dutzend Versionsprünge weiter bei 7.5.0. Und jetzt wird der
LPC-Link nicht mehr erkannt (die neuen USB Treiber wurden installiert).
Ich habe noch den LPC-Link2, aber da muss ich erst ein Adapterkabel
basteln.
/* Process the data through the CFFT/CIFFT module */
7
arm_cfft_radix4_f32(&S,pData);
8
9
uint32_tit2=CORE_GetSysTick()-it;
10
11
GPIO_ClearValue(0,(1<<6));
Wenn ich die Zeit messe die P0.6 hight ist dann dauert die FFT
Berechnung ca. 25,2 ms. Sind jetzt keine simulierten Daten sondern vom
ADC, die Zeit schwankt so um 0,2 ms.
Ich habe auch mal den Zyklenzähler eingebaut nach
Beitrag "Re: Floating Pointing Unit STM32F4"
Der zeigt mir ca. 3.020.000 Zyklen, das passt zu den 25,2 ms bei 120 MHz
Takt. Ist aber deutlich mehr als deine 125.000 Zyklen (der LPC1769 ist
aber auch ein M3, also ohne FPU).
Die Optimierung war -Os oder -O2, kein grosser Unterschied. Die
fftlength ist 1024, die arbeitet auf einen 2048 Werte Buffer.
Jojo S. schrieb:> Wenn ich die Zeit messe die P0.6 hight ist dann dauert die FFT> Berechnung ca. 25,2 ms. Sind jetzt keine simulierten Daten sondern vom> ADC, die Zeit schwankt so um 0,2 ms.
Das halte ich für erklärbar, eine software basierende Float-Operation
hat je nach dem wie die Mantissen gegenüber verschoben werden müssen
nicht immer die gleiche Ausführungsdauer.
> Ich habe auch mal den Zyklenzähler eingebaut nach> Beitrag "Re: Floating Pointing Unit STM32F4"> Der zeigt mir ca. 3.020.000 Zyklen, das passt zu den 25,2 ms bei 120 MHz> Takt. Ist aber deutlich mehr als deine 125.000 Zyklen (der LPC1769 ist> aber auch ein M3, also ohne FPU).
Sehe ich auch so.
> Die Optimierung war -Os oder -O2, kein grosser Unterschied.
Dito.
Kleines Update von mir:
Ich hat heute statt der arm_cortexM4lf_math die beiden arm_mathL_x
gelinkt.
Das hat bei der FFT keine wirklichen Unterschied gemacht, allerdings
reduzierte sich die Gesamtgröße auf 7 KB als ich alles bis auf die
arm_sin_f32 auskommentiert hatte.
Mit den arm_mathxx_x stehen nicht alle Funktionen die die
arm_cortexM4lf_math hat zur Verfügung, z.B. fehlt die arm_rfft_fast_f32.
Ich werde noch ein bischen Recherche betreiben; finde es etwas sinnfrei
von ARM eine Lib zu erstellen, die so groß ist, dass man sie nur in
Controller mit massig Flash laden kann.
Leon