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