Zarovnani v LPC11U68

Tomáš Hamouz hamouz na divesoft.cz
Úterý Červenec 12 08:51:50 CEST 2016


Když už píšete o potřebě nejnovějších kompilátorů, tak zrovna minulý
týden jsem řešil podobný problém.

Používám CLANG (je restriktivnější) a po posledním upgrade IDE
(Crossworks, včetně překladačů) mi to začalo házet výjimky na
nezarovnaná data.
Ukázalo se, že zřejmě optimalizační logiku přehnali, nebo udělali
defaultně zarovnání na 1.

Typický případ:

// data z akcelerometru
typedef struct {
    uint8_t osa_x;
    uint8_t osa_y;
    uint8_t osa_z;
} t_accm_data;

t_accm_data    accm_average_buffer[ACCM_AVERAGE_LENGTH];


void add_accm_data(t_accm_data* new_data) {
     ... posun pointeru idx
     accm_average_buffer[idx] = *new_data;
}


Přiřazení celé struktury se přeloží jako přesun 16b a pak 8b.
Jenže sizeof(t_accm_data) je 3 a tím pádem při druhém průchodu se čte
16b z liché adresy :-(

V předchozí verzi to fungovalo a když to přeložím GCC tak to funguje
taky. Musel jsem udělat ruční zarovnání a přidat čtvrtý byte do
struktury.
A ani to nebylo všechno, ukázalo se že pole accm_average_buffer je
taky nezarovnané. Zřejmě předpokládají že když struktura obsahuje samé
1B položky, tak ji není nutné zarovnávat. Ale ještě to neřekli těm
kteří píšou kopírování celých struktur :-/

Tomáš


> To máte pravdu, ale nijak to neodporuje mému tvrzení. Pokud požadavek na
> zarovnání pro překladač vznesete, ten jej může akceptovat a 
> optimalizovat podle něj, nebo jej ignoruje a optimalizaci neprovede.
> Pokud takový požadavek nedáte, překladač nemůže činit žádný předpoklad o
> zarovnání a optimalizovat tedy nemůže.
> Narazil jsem na to při implementaci FFT v celých číslech pro cortex-m0,
> pro určitou verzi gcc se neprovedlo zarovnání dat a celé to dlouho 
> trvalo, protože se kopírovaly jednotlivé byty. Teď jsem to pro jistotu
> znovu zkoušel a v současné verzi gcc 4.9.3 je toto chování opraveno, 
> zarovnání se provede automaticky i bez explicitního 
> __attribute__((aligned(4))). Je vidět, že lidi mrmlají a ku podivu gcc
> na to reaguje. Takže máte úplnou pravdu - je ještě 3. možnost - 
> požadavek nevznesete a překladač si to udělá po svém (a správně), včetně
> optimalizace. Asi to chce používat co nejnovější software. I když i to
> bývá riziko, je to zkrátka už moc složité.

> Mrazík

> Dne 11.7.2016 v 12:42 Tomáš Hamouz napsal(a):
>> Až dosud jsem byl přesvědčen že __attribute((aligned(n)))) je
>> _požadavek_ na compiler/linker, aby danou proměnnou umístil dle
>> požadavku, nikoliv informace jak je proměnná zarovnaná.
>>
>> Tedy říkáte jak "má být", nikoliv jak "je".
>>
>> Tomáš
>>
>>
>>>
> _______________________________________________
> HW-list mailing list  -  sponsored by www.HW.cz
> Hw-list na list.hw.cz
> http://list.hw.cz/mailman/listinfo/hw-list



Další informace o konferenci Hw-list