Biblioteka CMSIS DSP Keil ARM

Witam,

Wlasnie przygladam sie FFT na Coetexa-M3 (stm32f103) i chce uzyc biblioteki napisanej przez Arm i Keil DSP CMSIS.

Bazujac na:

formatting link
dalej przykladzie: CMSIS_5\CMSIS\DSP\Examples\ARM\arm_fft_bin_example\ wersja ewaluacyjan Keila generuje 8kB

compiling system_ARMCM3.c... linking... Program Size: Code=8032 RO-data=12032 RW-data=8208 ZI-data=8296 ".\ARMCM3_debug\arm_fft_bin_example.axf" - 0 Error(s), 0 Warning(s). Build Time Elapsed: 00:00:00

Ten sam przyklad z biblioteka skompilowana pod arm-none-eabi gcc 7.2.0 zajmuje 85kB !!

Invoking: Cross ARM GNU Print Size arm-none-eabi-size --format=berkeley "stm32f103_dsp_cmsis5.elf" text data bss dec hex filename 82524 76 1320 83920 147d0 stm32f103_dsp_cmsis5.elf Finished building: stm32f103_dsp_cmsis5.siz

Czy ktos zana pood, dlaczego prosty przyklad:

arm_rfft_fast_instance_f32 S; arm_cfft_radix4_instance_f32 cfft;

static arm_rfft_instance_q15 Sq15;

volatile static uint32_t result ; result = arm_rfft_init_q15(&Sq15, 128, 0, 1);

for(int i=0; i < 128; i++){ q15InData[i] = (q15_t)(sin3x[i] * 2048.0); }

volatile static q15_t magnitude[128]; arm_rfft_q15(&Sq15, (q15_t*)q15InData, (q15_t*)fft_results);

arm_cmplx_mag_q15((q15_t*)fft_results, (q15_t*)magnitude, 128 );

kompiluje sie do 10x wiekszego rozmiaru przy GCC ? Wiedzialem ze GCC jest mniej zoptymalizowane, ale zeby 10x wiekszy kod generowac to juz przesada.

Marcin

Reply to
Marcin
Loading thread data ...

Laczenie. Jak sie patrzylem to GCC generowal bardzo dobry kod (nie robilem porownan z Keilem, ale po prostu przy jakosci GCC nie ma wiele miejsca na poprawe). Natomiast duzy program zwykle bierze sie z dolaczania niepotrzebnych rzeczy. Trzeba zbadac co jest laczone i dlaczego. Typowa pulapka to funkcja biblioteczna ktora chce wypisac komunikat o bledzie i dolacza cala mase potrzebnego do tego kodu. Czasami aby unikniec dolaczania zbednego kodu trzeba robic dosc brutalne rzeczy w stylu zdefiniowania wlasnej wersji wewnetrznej funkcji (ktora nic nie robi w ten sposob unika zaleznosci).

Reply to
antispam

W dniu 14.12.2017 o 16:56, Marcin pisze:

Nie podałeś z jakimi flagami kompilujesz program, czy włączyłeś optymalizację, czy każesz kompilatorowi usunąć nieużywane funkcje i dane z programu. Na początek dodaj flagi -Os -ffunction-sections

-fdata-sections do kompilacji oraz -Wl,--gc-sections do wywołania linkera. Sprawdź też jak wygląda rozmiar po kompilacji na Cortexa M4. Jeśli wtedy rozmiar mocno spadnie, to winna może być software'owa emulacja floatów. Komercyjne pakiety (także te korzystające z gcc) mają często biblioteki ręcznie dłubane w assemblerze i stąd różnica w prędkości/wielkości.

Reply to
Zbych

Czesc, optymalizacja kompilatora dokladnie jak proponujesz: -0s, probowalem tez -O3 ale niewiele sie zmienia. linker tez powinien usuwac zbedny kod (-ffunction-sections -fdata-sections ), newlib nano ( nie powinno miec znaczenia)

Przyklad ktory testuej uzywa staloprzecinkowych Q15, wiec floatow nie powinno nigdzie byc.

Kod zrodlowy CMSIS DSP jest dostepny i biblioteki dla Keila i GCC kompilowalem sam. Z tego co wypatrzylem sa uzywane duze tablice wspolczynnikow ( dla roznych dlugosci FFT rozne tablice) w stylu:

arm_rfft_init_q15(){ switch (S->fftLenReal) { case 8192U: S->twidCoefRModifier = 1U; S->pCfft = &arm_cfft_sR_q15_len4096; break; case 4096U: S->twidCoefRModifier = 2U; S->pCfft = &arm_cfft_sR_q15_len2048; break; case 2048U: S->twidCoefRModifier = 4U; S->pCfft = &arm_cfft_sR_q15_len1024; break; case 1024U: S->twidCoefRModifier = 8U; S->pCfft = &arm_cfft_sR_q15_len512; break; case 256U: S->twidCoefRModifier = 32U; S->pCfft = &arm_cfft_sR_q15_len128; break; case 128U: S->twidCoefRModifier = 64U; S->pCfft = &arm_cfft_sR_q15_len64; break; case 64U: S->twidCoefRModifier = 128U; S->pCfft = &arm_cfft_sR_q15_len32; break; case 32U: S->twidCoefRModifier = 256U; S->pCfft = &arm_cfft_sR_q15_len16; break; .... } moje podejrzenie jest, ze Keil widzac ze wywoluje ze stala dlugoscia 128, potrafi "wyrzucic" niepotrzebne struktury const typu arm_cfft_sR_q15_len1024 ( ktore sa np. 3000 x uint16_t)

Bede musial sie dokladniej przygladnac .map i .lst z GCC, co faktacznie jest w zlinkowanym pliku .elf

I kolejne pytanie - _wydawalo_ mi sie, ze biblioteki skompilowane roznymi kompilatorami powinny byc kmpatybilne ( ARM calling convention) ale biblioteki z Keila nie linkuja sie w GCC :(

Marcin

Reply to
Marcin

W dniu 15.12.2017 o 11:52, Marcin pisze:

Do kompilacji -Os -ffunction-sections -fdata-sections a do linkowania -Wl,--gc-sections

To by sugerowało, że jednak nie usuwasz zbędnych danych.

Może ABI jest zgodne, ale binarny format bibliotek jest inny? Czyli możesz z gcc wywołać funkcję z wbudowaną w ROM uC, ale nie zlinkujesz bibliotek.

Reply to
Zbych

Zracam honor GCC - blad Layer 8. Wszystkie flagi byly poprawne, linker usuwal co mogl.

w projekcie Keila jest plik main.c, w ktorym jest to co skopiowalem do GCC

result = arm_rfft_init_q15(&Sq15, 128, 0, 1); arm_rfft_q15(&Sq15, (q15_t*)q15InData, (q15_t*)fft_results);

tyle ze ten plik jest wylaczony z kompilacji i faktycznie main jest brane z arm_fft_bin_example_f32.c gdzie jest wywolanie

arm_cfft_f32(&arm_cfft_sR_f32_len1024, testInput_f32_10khz, ifftFlag, doBitReverse); arm_cmplx_mag_f32(testInput_f32_10khz, testOutput, fftSize); arm_max_f32(testOutput, fftSize, &maxValue, &testIndex);

Moja wina, ze porownywalem jednak 2 rozne programy.... Dalej widze roznice ale ok. 2x.

Jak juz zaczalem kopac, to ciekawosci przygladne sie jaka jest roznica w rozmiarze i kodzie funkcji biblioteki generowanych przez Keila i GCC. na szczescie .axf Keila jest tym samym co elf i arm-none-eabi-objdump ladnie to disassembluje.

Reply to
Marcin

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.