GCC optimalizace, zahada - vyreseno

Jaroslav Buchta jaroslav.buchta na hascomp.cz
Neděle Listopad 5 10:32:57 CET 2017


Takze nakonec byla chyba v casovani, prekladac je OK a spadl mi 
sutr....  ;-)
Kod na konci je asi max. rychly a funkcni, klicove je zvyraznene DSB po 
WR->1, musi tam byt ne predstih ale nejaky presah dat a procesor to 
zvlada evidentne extremne rychle, ted to ale nemam cim zmerit Je mozne, 
ze by se zapisy na ruzne GPIO spojili do jednoho cyklu nebo i predbehly?.
A str vs str.w asi zavisi na pouzitych registrech, ze? 16b str umi 
pracovat jen s R0..R7 predpokladam, o zarovnani to evidentne nebude. 
(ale zkoumat celou instrukcni sadu zatim nehodlam)

130               APPLYDOREGS(AL, BL, CL);
08001730:   str.w   r12, [r3, #24]
08001734:   str     r0, [r4, #24]
08001736:   str.w   r7, [r8, #24]        ...nezarovnano
nebo
0800171c:   str     r5, [r3, #24]
0800171e:   str     r1, [r4, #24]
08001720:   str.w   r6, [r8, #24]
08001724:   str     r2, [r3, #40]   ; 0x28
---------------------------------------------------------------
funkcni kod, pokud ma nekdo napad na dalsi zrychleni... ;-)

#pragma GCC push_options
#pragma GCC optimize ("O3")


#define PREPAREDOREGS(A,B,C,v)    A =  ((v)&0x01) ? (uint32_t)TFT_D0_Pin 
: ((uint32_t)TFT_D0_Pin) << 16;\
                                 C =  ((v)&0x02) ? (uint32_t)TFT_D1_Pin 
: ((uint32_t)TFT_D1_Pin) << 16;\
                                 A |= ((v)&0x04) ? (uint32_t)TFT_D2_Pin 
: ((uint32_t)TFT_D2_Pin) << 16;\
                                 B =  ((v)&0x08) ? (uint32_t)TFT_D3_Pin 
: ((uint32_t)TFT_D3_Pin) << 16;\
                                 B |= ((v)&0x10) ? (uint32_t)TFT_D4_Pin 
: ((uint32_t)TFT_D4_Pin) << 16;\
                                 B |= ((v)&0x20) ? (uint32_t)TFT_D5_Pin 
: ((uint32_t)TFT_D5_Pin) << 16;\
                                 B |= ((v)&0x40) ? (uint32_t)TFT_D6_Pin 
: ((uint32_t)TFT_D6_Pin) << 16;\
                                 A |= ((v)&0x80) ? (uint32_t)TFT_D7_Pin 
: ((uint32_t)TFT_D7_Pin) << 16


#define APPLYDOREGS(A,B,C)    GPIOA->BSRR = A;\
                             GPIOB->BSRR = B;\
                             GPIOC->BSRR = C

static void TftFillData (uint16_t w, int len)
{
      uint32_t AH,AL,BH,BL,CH,CL;

     TFT_RS_TPYA_GPIO_Port->BRR = TFT_RS_TPYA_Pin;
     TFT_NCS_GPIO_Port->BRR = TFT_NCS_Pin;

     PREPAREDOREGS(AH, BH, CH, 0x2c);
     APPLYDOREGS(AH, BH, CH);
     TFT_NWR_TPXA_GPIO_Port->BRR = TFT_NWR_TPXA_Pin;
     __DSB();
     TFT_NWR_TPXA_GPIO_Port->BSRR = TFT_NWR_TPXA_Pin;

     TFT_RS_TPYA_GPIO_Port->BSRR = TFT_RS_TPYA_Pin;
     PREPAREDOREGS(AH, BH, CH, (uint8_t)(w >> 8));
     PREPAREDOREGS(AL, BL, CL, (uint8_t)(w & 0xff));
     while (len--)
     {
         APPLYDOREGS(AH, BH, CH);
         TFT_NWR_TPXA_GPIO_Port->BRR = TFT_NWR_TPXA_Pin;
         __DSB();
         TFT_NWR_TPXA_GPIO_Port->BSRR = TFT_NWR_TPXA_Pin;
*__DSB();*
         APPLYDOREGS(AL, BL, CL);
         TFT_NWR_TPXA_GPIO_Port->BRR = TFT_NWR_TPXA_Pin;
         __DSB();
         TFT_NWR_TPXA_GPIO_Port->BSRR = TFT_NWR_TPXA_Pin;
     }
     TFT_NCS_GPIO_Port->BSRR = TFT_NCS_Pin;
}



Dne 04.11.2017 v 9:52 Jaroslav Buchta napsal(a):
> Jak uz jsem psal, to pretypovani taky uplne nepomohlo, jen se zmenilo 
> chovani. Ty inline funkce zkusim, makro jsem udelal, protoze mi to 
> prislo jako dobry navod pro prekladac, ze z toho opravdu nema udelat 
> normalni funkci.
> Nejdriv ale zkusim probadat ten assembler, je to ale opravdu 
> neprehledne, vse je v registrech a divne offsetovano. Pricina problemu 
> mne opravdu zajima. Displej by mel data zapsat vzestupnou hranou a DSB 
> + ISB zajisti asi 150ns prodlevu WR v 0 i podle mereni, takze v 
> casovani asi problem nebude.

------------- další část ---------------
HTML příloha byla odstraněna...
URL: <http://list.hw.cz/pipermail/hw-list/attachments/20171105/3339285d/attachment.html>


Další informace o konferenci Hw-list