Uproszczenie funkcji

W tym miejscu zadajemy pytania na temat języka C, dzielimy się swoją wiedzą, udzielamy wsparcia, rozwiązujemy problemy programistyczne.
Awatar użytkownika
StaryAnoda_NEW
User
User
Posty: 103
Rejestracja: środa 04 kwie 2018, 16:48

Uproszczenie funkcji

Postautor: StaryAnoda_NEW » niedziela 15 kwie 2018, 14:49

Hej

Czy może ktoś zobaczyć bardziej doświadczony. Czy taką funkcję można zoptymalizować by wykonywała się szybciej ?
Niestety nie mam możliwości modyfikowania wersji sprzętowej podłączenia.

Kod: Zaznacz cały

static void SPFD5408_write_byte(uint8_t byte)
{
   if(byte & 1)GPIOA->BSRR = GPIO_BSRR_BS9; else  GPIOA->BRR = GPIO_BRR_BR9;
   if(byte & 2)GPIOC->BSRR = GPIO_BSRR_BS7; else GPIOC->BRR = GPIO_BRR_BR7;
   if(byte & 4)GPIOA->BSRR = GPIO_BSRR_BS10; else GPIOA->BRR = GPIO_BRR_BR10;
   if(byte & 8)GPIOB->BSRR = GPIO_BSRR_BS3; else GPIOB->BRR = GPIO_BRR_BR3;
   if(byte & 16)GPIOB->BSRR = GPIO_BSRR_BS5; else GPIOB->BRR = GPIO_BRR_BR5;
   if(byte & 32)GPIOB->BSRR = GPIO_BSRR_BS4 ; else GPIOB->BRR = GPIO_BRR_BR4;
   if(byte & 64)GPIOB->BSRR = GPIO_BSRR_BS10; else GPIOB->BRR = GPIO_BRR_BR10;
   if(byte & 128)GPIOA->BSRR = GPIO_BSRR_BS8; else GPIOA->BRR = GPIO_BRR_BR8;
   SPFD5408_WR_STROBE;
}

Awatar użytkownika
xor
User
User
Posty: 169
Rejestracja: poniedziałek 05 wrz 2016, 21:44

Re: Uproszczenie funkcji

Postautor: xor » niedziela 15 kwie 2018, 19:54

Możesz na początku całkowicie zresetować piny a dopiero potem w kolejnych warunkach je ustawiać. Pozbędziesz się w ten sposób części po "else" (czyli jednego skoku na instrukcję).

Lookup table. Nie wiem czy to będzie szybciej, ale na pewno pochłonie duuużo więcej pamięci flash ;-):

Kod: Zaznacz cały

static void SPFD5408_write_byte(uint8_t byte)
{
static const uint32_t array[256] = {
//0
      GPIO_BRR_BR9|GPIO_BSRR_BR7|GPIO_BSRR_BR10|GPIO_BSRR_BR3|GPIO_BSRR_BR5
              |GPIO_BSRR_BR4|GPIO_BSRR_BR10|GPIO_BSRR_BR8,
//1
      GPIO_BRR_BS9|GPIO_BSRR_BR7|GPIO_BSRR_BR10|GPIO_BSRR_BR3|GPIO_BSRR_BR5
              |GPIO_BSRR_BR4|GPIO_BSRR_BR10|GPIO_BSRR_BR8,
//2
      GPIO_BRR_BR9|GPIO_BSRR_BS7|GPIO_BSRR_BR10|GPIO_BSRR_BR3|GPIO_BSRR_BR5
              |GPIO_BSRR_BR4|GPIO_BSRR_BR10|GPIO_BSRR_BR8,
//3
      GPIO_BRR_BS9|GPIO_BSRR_BS7|GPIO_BSRR_BR10|GPIO_BSRR_BR3|GPIO_BSRR_BR5
              |GPIO_BSRR_BR4|GPIO_BSRR_BR10|GPIO_BSRR_BR8,
//...
//255
      GPIO_BRR_BS9|GPIO_BSRR_BS7|GPIO_BSRR_BS10|GPIO_BSRR_BS3|GPIO_BSRR_BS5
              |GPIO_BSRR_BS4|GPIO_BSRR_BS10|GPIO_BSRR_BS8
};

   GPIOA->BSRR = array[byte];

   SPFD5408_WR_STROBE;
}

Awatar użytkownika
Antystatyczny
Geek
Geek
Posty: 1168
Rejestracja: czwartek 03 wrz 2015, 22:02

Re: Uproszczenie funkcji

Postautor: Antystatyczny » niedziela 15 kwie 2018, 20:06

xor pisze:Lookup table

Pomysł nie jest głupi i często tablicuje się takie dziwolągi, ale zauważ, że tutaj uzyskujemy dostęp do GPIOA oraz GPIOB, a zatem należy w tablicy zapamiętać port oraz bit, a to już zaczyna być nieopłacalne. Rozważyłbym opcję Anody, ale z wykorzystaniem bitbandingu. Polecam lekturę tego tematu.
"The true sign of intelligence is not knowledge but imagination" Albert Einstein.

Awatar użytkownika
dambo
Expert
Expert
Posty: 645
Rejestracja: czwartek 17 mar 2016, 17:12

Re: Uproszczenie funkcji

Postautor: dambo » niedziela 15 kwie 2018, 20:19

xor pisze:Możesz na początku całkowicie zresetować piny a dopiero potem w kolejnych warunkach je ustawiać. Pozbędziesz się w ten sposób części po "else" (czyli jednego skoku na instrukcję).


chyba najlepsze wyjście z sytuacji - zwłaszcza dla GPIOB, gdzie są 4 piny używane. Wtedy zamiast 4 elsów mamy jedną instukcję przypisania na początku. Dla innych też śmiało to można zastosować.

BB byłby tu fajny, jakby z RAMu można było to czytać. Wtedy wartość jakiegoś bitu (GPIO->ODRx) byłaby wartością innego bitu (poszczególne bity z zmiennej). Niestety BB nie obejmuje swoim zasięgiem pamięci RAM.
Przyszedł mi pomysł na jego obejście - ale jako ciekawostka, raczej tak nie robić :p - można użyc rejestru kontrolnego innego nieużywanego peryferium - do niego wklepać ta zmienną i potem mamy BB w dwie strony. Inna kwestia, czy wtedy gra jest warta świeczki :p

Swoją drogą - możemy teraz kombinować, a potem włączysz optymalizację w kompilatorze i będziesz miał wynik z 30% lepszy
Nowy blog o tematyce embedded -> https://www.embedownik.pl/

Awatar użytkownika
xor
User
User
Posty: 169
Rejestracja: poniedziałek 05 wrz 2016, 21:44

Re: Uproszczenie funkcji

Postautor: xor » niedziela 15 kwie 2018, 20:42

Antystatyczny pisze:...dostęp do GPIOA oraz GPIOB...

...oraz GPIOC, jakoś mi to umknęło :shock: :?
dambo pisze:BB byłby tu fajny, jakby z RAMu można było to czytać. Wtedy wartość jakiegoś bitu (GPIO->ODRx) byłaby wartością innego bitu (poszczególne bity z zmiennej). Niestety BB nie obejmuje swoim zasięgiem pamięci RAM.

No jak nie obejmuje: "In the STM32F10xxx both peripheral registers and SRAM are mapped in a bit-band region." (z RM dla F103)

Awatar użytkownika
dambo
Expert
Expert
Posty: 645
Rejestracja: czwartek 17 mar 2016, 17:12

Re: Uproszczenie funkcji

Postautor: dambo » niedziela 15 kwie 2018, 21:02

Mój błąd - ubzdurało mi się, że w M0 nie można mapować - coś źle zrozumiałem na początku nauki zapewne(a M0 się wzięło z innego dzisiejszego wątku) - no to już wszystko jasne. Musze się tym pobawić kiedyś na spokojnie.

To przy BB dochodzi inny aspekt - w przypadku peryferii nie zmieni się nam adres rejestru/bitu, a w przypadku takiej funkcji się zmieni. Czyli trzeba to inaczej przekazywać - przez taką zmienną, której adres będziemy znać na etapie kompilacji, żeby go nie przeliczać w funkcji, bo wtedy to nam nic nie przyspieszy.
Nowy blog o tematyce embedded -> https://www.embedownik.pl/

Awatar użytkownika
StaryAnoda_NEW
User
User
Posty: 103
Rejestracja: środa 04 kwie 2018, 16:48

Re: Uproszczenie funkcji

Postautor: StaryAnoda_NEW » środa 18 kwie 2018, 15:55

Ok to tak na tym etapie chyba zostanę przy takim 'dziwolągu' jaki mam, BIT BANDING nie przyspieszył wykonywania tej funkcji a nawet ją opóźnił. A wrzucanie do tablicy nie wydaję mi się rozsądne ze względu na zasoby pamięci jakie pochłonie.


Wróć do „Pisanie programów w C”

Kto jest online

Użytkownicy przeglądający to forum: Obecnie na forum nie ma żadnego zarejestrowanego użytkownika i 3 gości