logo elektroda
logo elektroda
X
logo elektroda
REKLAMA
REKLAMA
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

ISR - Użycie wielu rejestrów w funkcji, optymalizacja, sterowanie bitami i portami IO

robiw 09 Wrz 2022 12:23 759 9
REKLAMA
  • #1 20181955
    robiw
    Poziom 26  
    Posty: 2032
    Pomógł: 25
    Ocena: 133
    Witajcie
    Mam dość prostą funkcję ISR, która korzysta z kilku zmiennych statycznych (flag typu uint8_t) oraz sprawdza stan (switchem) jednej zmiennej globalnej (oczywiście volatile) by sterować swoim działaniem w wyniku którego ustawia (lub odczytuje) poszczególne bity kolejnych bajtów niewielkich tablic globalnych (typu uint8_t) oraz wachluje portem IO. W zasadzie to wszystko, co robi, nie wykonując żadnej arytmetyki (poza sprawdzaniem/ustawianiem bitów zmiennych i indeksowaniem tablic)...a mimo wszystko kompilator odkłada w prologu ponad 11 rejestrów procesora (większość między R18 a R31, plus tradycyjne R0 i R1). Dość dużo, jak na mój gust, czy normalne? Zastanawiam się, jak to zoptymalizować. robiw
  • REKLAMA
  • REKLAMA
  • #3 20182247
    tmf
    VIP Zasłużony dla elektroda
    Posty: 14318
    Pomógł: 2090
    Ocena: 2206
    Podaj wersję kompilatora. W nowszych zostało to poprawione i kompilator odkłada tylko te rejestry, które używa. Niemniej, nawet w tak prostym kodzie może używać ich wiele, bo w większości przypadków nie wiąże się to z żadnymi kosztami, więc optymalizator nie jest na to nastawiony. Zauważ, że w C nie ma koncepcji przerwań, więc kompilator nie do końca wie, że w tym przypadku redukcja liczby rejestrów ma sens.
    BTW, jeśli tylko odczytujesz stan zmiennej w przerwaniu to nie musi ona być volatile.
  • #4 20182248
    robiw
    Poziom 26  
    Posty: 2032
    Pomógł: 25
    Ocena: 133
    Hej.
    To wiadomo, że asembler rozwiązałby problem, ale nie chcę tego robić, bo funkcja,.mimo że prosta, jest długa. Co do wywołań to wiadomo, że w ciele ISR nie wywołuje innych funkcji poza funkcją inline i _delay_us (jest niezbędna) ale one nie są wywoływane tylko wprowadzane w miejscu wywołania. ISR nie jest taka częsta, ale ważna jest dla niej latencja. Poza tym chciałem się upewnić, czy nie da się tego zoptymalizować... R
  • #5 20182253
    tmf
    VIP Zasłużony dla elektroda
    Posty: 14318
    Pomógł: 2090
    Ocena: 2206
    robiw napisał:
    ważna jest dla niej latencja

    Jeśli to jest naprawdę ważne, to zostaje raczej tylko asembler.
    robiw napisał:
    ie wywołuje innych funkcji poza funkcją inline i _delay_us (jest niezbędna) ale one nie są wywoływane tylko wprowadzane w miejscu wywołania

    To wcale nie jest takie oczywiste, inline nie wymusza osadzenia kodu, jest tylko sugestią.
  • REKLAMA
  • #6 20182254
    robiw
    Poziom 26  
    Posty: 2032
    Pomógł: 25
    Ocena: 133
    tmf napisał:
    Podaj wersję kompilatora. W nowszych zostało to poprawione i kompilator odkłada tylko te rejestry, które używa. Niemniej, nawet w tak prostym kodzie może używać ich wiele, bo w większości przypadków nie wiąże się to z żadnymi kosztami, więc optymalizator nie jest na to nastawiony. Zauważ, że w C nie ma koncepcji przerwań, więc kompilator nie do końca wie, że w tym przypadku redukcja liczby rejestrów ma sens.
    BTW, jeśli tylko odczytujesz stan zmiennej w przerwaniu to nie musi ona być volatile.


    Zmienne są nie tylko odczytywane, ale także aktualizowane. Może to kwestia użycia tablic...a co do rejestrów to on je odkłada, bo używa ich w ISR...ale po co aż tyle to nie wiem. R

    Dodano po 7 [minuty]:

    tmf napisał:
    To wcale nie jest takie oczywiste, inline nie wymusza osadzenia kodu, jest tylko sugestią.


    Wiem o tym. Sprawdzałem w kodzie, jak to skompilował. Podobnie z _delay_us. Co do asemblera to wiadomo, ale chciałem rozeznać, czy da się to jakoś zoptymalizować, bo nie bardzo widzę sens używania aż tylu rejestrów... R

    Dodano po 3 [godziny] 45 [minuty]:

    tmf napisał:
    BTW, jeśli tylko odczytujesz stan zmiennej w przerwaniu to nie musi ona być volatile.


    Jesteś pewien? Z czego to wynika? Dotyczy też tablic? Przyszło mi do głowy, jak nieco zoptymalizować kod. Otóż zmienną Status, która jest volatile i jest często testowana w ISR wczytam na początku do zmiennej lokalnej, na niej będę wykonywał operacje a przed wyjściem z ISR zaktualizuję zmienną globalną. Tak z resztą mogę postąpić z każdą zmienną tego typu. Zwykle tak robiłem a teraz wypadło mi to kompletnie z głowy. Pytałeś o kompilator. IDE Microchip Studio 7.0, więc chyba avrgcc 5.4.0... R
  • #7 20182732
    tmf
    VIP Zasłużony dla elektroda
    Posty: 14318
    Pomógł: 2090
    Ocena: 2206
    robiw napisał:
    esteś pewien? Z czego to wynika? Dotyczy też tablic?

    Jeśli w ISR tylko odczytujesz stan zmiennej, to volatile nic nie zmienia - i tak program musi za każdym razem przy wejściu do ISR pobrać jej stan. Co innego, jeśli zmienna jest modyfikowana - żeby reszta kodu nie była nadmiernie zoptymalizowana to trzeba dać volatile.
    Poza tym do przekazywania wartości do ISR użyj GPR, powinno być szybciej.
  • REKLAMA
  • #8 20182767
    robiw
    Poziom 26  
    Posty: 2032
    Pomógł: 25
    Ocena: 133
    tmf napisał:
    Poza tym do przekazywania wartości do ISR użyj GPR, powinno być szybciej.


    To dobry pomysł. Dzięki.

    robiw napisał:
    Przyszło mi do głowy, jak nieco zoptymalizować kod. Otóż zmienną Status, która jest volatile i jest często testowana w ISR wczytam na początku do zmiennej lokalnej, na niej będę wykonywał operacje a przed wyjściem z ISR zaktualizuję zmienną globalną.


    A to o dziwo się nie sprawdziło. Dziwne, bo w ISR zmienna volatile jest testowana wiele razy, więc "przekazanie" jej w ten sposób powinno skrócić kod...a nie skraca. Chyba, że już wcześniej optymalizator zrobił, co trzeba... R

    Dodano po 4 [minuty]:

    tmf napisał:
    Poza tym do przekazywania wartości do ISR użyj GPR, powinno być szybciej.


    Kod zmniejszył się o 30 bajtów, ale latencja w ogóle. Nadal odkłada tyle samo rejestrów...R
  • #9 20182860
    jarekgol
    Poziom 40  
    Posty: 5187
    Pomógł: 645
    Ocena: 1151
    co to jest GPR? Rejestr R-ileś?

Podsumowanie tematu

LABEL_AI_GENERATED
Użytkownik zadał pytanie dotyczące optymalizacji funkcji ISR, która korzysta z wielu zmiennych statycznych i globalnych, a także steruje portem IO. Zauważył, że kompilator odkłada ponad 11 rejestrów procesora, co wydaje się nadmierne. Odpowiedzi sugerują, że nowsze wersje kompilatora lepiej zarządzają rejestrami, a także wskazują na możliwość użycia lokalnych zmiennych do optymalizacji. Użytkownik rozważał użycie asemblera, ale preferuje rozwiązania w C. Wskazano również, że zmienne volatile są istotne tylko przy ich modyfikacji, a do przekazywania wartości do ISR zaleca się użycie rejestrów ogólnego przeznaczenia (GPR). Użytkownik zauważył, że mimo optymalizacji kodu, liczba odkładanych rejestrów pozostaje wysoka.
Podsumowanie AI na podstawie dyskusji. Może zawierać błędy.
REKLAMA