Bitove polia a optimalizacia kody Was: STM32F051K6U7 ma USART2 ?

Milan B. milan na bastl.sk
Neděle Březen 15 21:58:38 CET 2015


On 15. 3. 2015 18:18, Miroslav Mraz wrote:
> Dovolím si k tomu ještě jednu drzou poznámku. Přesně toto je důvod, 
> proč přepsat definice registrů do bitových polí. 

Ked uz sa tu odporucaju bitove polia, tak ma napadlo overit, ako ich 
kompilator dokaze optimalizovat.

Skusal som GCC  4.9.3 20141119 (ARM Embedded). Vysledok bol zaujimavy, 
tak som si ho overil na dalsich dvoch portoch - MSP430 (4.9.1) a x86 
(4.8.2) - s rovnakym vysledkom, takze je to vlastnost GCC ako takeho:

GCC dokaze spojit do jednej operacie nastavovanie jednobitovych poloziek 
v ramci jednoho byte. Akonahle sa nastavuju polozky patriace do roznych 
byte, robi to na viackrat.
Viacbitove polozky sa vzdy riesia samostatne.

Priklad:
Majme 16-bitove pole:
struct {
  unsigned int b1:1;
  unsigned int b2:6;
  unsigned int b3:1;
  unsigned int b4:1;
  unsigned int b5:6;
  unsigned int b6:1;
} b;

Velkost jednoduchej funkcie nastavujucej dve jednobitove polozky (aj s 
prologom a epilogom, nechcelo sa mi ich odpocitavat):
void test()
{
   b.b1=1;
   b.b3=1;
}

je u ARM (kompilovane s -march=armv7e-m -mthumb a optimalizaciami -O2 aj 
-Os) 16 byte. Oba bity su v ramci jednoho byte.

Ak su jednobitove polozky v dvoch roznych byte:
   b.b1=1;
   b.b4=1;
Tak je velkost kodu 24 byte.

Ak su polozky v jednom byte, ale jedno je viacbitove:
  b.b1=1;
  b.b2=1;
Tak je velkost 20 byte (-O2) alebo 24 byte (-Os).

A nakoniec to iste, ale viacbitova polozka je v druhom byte:
  b.b1=1;
  b.b5=1;
Tu je velkost kodu 24 byte (-O2) alebo 28 byte (-Os).

Najvacsie prekvapenie nastalo, ked som to porovnal s "klasickym" 
nastavovanim bitov cez bitovy OR:
  a|=0x1001u;
Velkost kodu bola 20 byte - trochu viac, ako som ocakaval.

Pohlad do vygenerovaneho kodu priniesol prekvapenie:
  orr     r3, r3, #4096
  orr     r3, r3, #1

Na tuto - trufam si povedat sprostost - nemam vysvetlenie. Toto je ale 
ciste problem portu GCC pre ARM, ostatne komilatory nemali s konstantou 
problem:
MSP430: BIS.W   #4097, &a
x86:    orw     $4097, a(%rip)

Takze optimalizacia prace s bitovymi polami nie je nic moc, a kvalita 
ARM portu GCC tiez zrejme nestoji za vela.

-m-



Další informace o konferenci Hw-list