Elektroda.pl
Elektroda.pl
X

Wyszukiwarki naszych partnerów

Kategoria: Kamery IP / Alarmy / Automatyka Bram
Montersi
Kategoria: Akumulatorki / Baterie / Ładowarki

Działania na dużych liczbach

krzysztofh 17 Mar 2017 11:39
  • #31 17 Mar 2017 11:39
    Piotrus_999
    Poziom 39  

    Chodziło ci o dane 32 bit a nie procesor - to ok.

  • #32 17 Mar 2017 12:03
    krzysztofh
    Poziom 28  

    Koledzy, procesor to Atmega 16 taktowana zegarem 16MHz i nie mogę jej zamienić na coś innego.
    Nie włączam się do dyskusji, bo to nie mój poziom, ale czytam wszystkie posty.

  • #33 17 Mar 2017 12:48
    Piotrus_999
    Poziom 39  

    krzysztofh napisał:
    Koledzy, procesor to Atmega 16 taktowana zegarem 16MHz i nie mogę jej zamienić na coś innego.
    Nie włączam się do dyskusji, bo to nie mój poziom, ale czytam wszystkie posty.


    Musisz w takim razie się pogodzić. Wszystko co ma wiecej niz 8 bitów zajmuje więcej czasu i przestrzeni bo to taki procesor po prostu. Dzielenie jest dość wolne bo niestety programowe i na danych więcej niż 8 bitów sporo operacji musi być wykonane,

  • #34 17 Mar 2017 22:30
    Sparrowhawk
    Poziom 20  

    Sprawdziłem jak umiałem (z pomocą timera), czas wykonania konwersji liczby INT32_MAX na Atmega168PB [16MHz]. Moja własna naiwna implementacja:

    Kod: c
    Zaloguj się, aby zobaczyć kod
    wykonuje się w najlepszym razie na -03: 343µs. W najgorszym na -Os: 781µs.
    Natomiast AVR Libc dostarcza nam gotową funkcję, która nie zależnie od wybranej optymalizacji wykonywała się w czasie: 223µs.

    W aktualnym numerze EP(03/17) pojawił się artykuł pt. "Osobliwości kompilatora AVR-GCC i mikrokontrolerów AVR (1)", w którym również przedstawiona jest funkcja na wzór ltoa(). Artykuł dostępny jest na stronie Elektroniki praktycznej.

    Przetestowałem i tę funkcję i otrzymałem od -03: 328µs do -Os: 347.

  • #35 18 Mar 2017 01:31
    malcompl
    Poziom 9  

    Szybciej niż z libc-a raczej nie da się osiągnąć, w jakimś sensowny czasie. Patrzyłem na ten kod, jest sprawnie napisany w asm-ie i niezależnie od ustawień kompilatora, czas wykonania będzie stały, który dałoby się oszacować. Funkcje te wykonują te same instrukcje różniące się jedynie obsługa większych rozmiarów, iteracyjnie w powtórzeniach równych co do rozmiaru typu. Niezależnie czy będzie 0x00000001, czy 0xFFFFFFFF, czas wykonania będzie taki sam. Ale można przyjąć, że 32- jest 2+ razy wolniejsze niż 16-, a te również 2+ razy niż 8-bit int.

    Jedyny zysk na cyklach można osiągnąć właśnie wykorzystując ten fakt, z kodem jaki już wyżej wspominaliśmy, aby zależnie od wartości wołać dedykowaną funkcję 32-, 16- czy 8- bitową. To oczywiście może być znacznie zauważalne, jeśli przetwarzane dane będą najczęściej trafiać w zakres 16- lub 8-, niż w 32-bitowy.

    Sam przez chwilę myślałem, że może dotknąć mnie ten problem w planowanym radiowym liczniku częstotliwości, który może przejdzie z pomysłu i planu do realizacji w jakimś sensownym czasie ;) Ale patrząc realnie, nawet przy czasie bramkowania 10ms, 6-ciu cyfrach, przeoranie 32-bitowych danych nawet z jakaś obróbką, czy uśrednianiem, będzie niezauważalne z punktu działania całości układu.

    Autor musiałby nieźle walić danymi do obróbki, aby mieć problem. A jakby chciał na żywo przetwarzać jakieś dane/sygnały z większą częstotliwością niż ewentualna ich prezentacją to chyba nie ta platforma ;)

    BTW Funkcje dzielnia z libc-a zwracają wynik z dzielenia i resztę, więc jeśli w pobliżu będzie operacja / i % na tych samych danych (co jest raczej pewne, przy rozbijaniu liczby na cyfry), to optymalizator kompilatora ładnie z tego faktu skorzysta, generując tylko jeden call.

  • #36 18 Mar 2017 08:17
    Wertyuud
    Poziom 18  

    Widzę, że autor chce zrobić konwersję liczby binarnej na BCD. Jest do tego specjalny algorytm, który nie używa mnożenie i dzielenia, tylko przesuwanie bitów i dodawanie warunkowe. Można poszukać w google pod nazwą "bin to bcd conversion algoriht", "Double-Dabble", "Shift-and-add-3 algorithm". Tutaj przykład. Zapewne jest gdzieś w sieci implementacja na AVR.

    Co do dzielenia modulo, to nie zawsze korzystanie z bibliotek standardowych jest optymalnie, bo wykonują one działania dla wszystkich możliwych przypadków (dzielenie przez dowolną liczbę !=0). Można napisać algorytm, który będzie dzielił tylko przez jedną możliwą liczę np. przez dziesięć, przez co będzie działał szybciej. Optymalizacja dzielenia jest dobrze opisana np. tu . Skleiłem dwa algorytmy z powyższej strony, żeby uzyskać wynik z dzielenia przez 10 i dzielenia modulo 10, ale nie wiem jaka będzie jego szybkość:

    Kod: c
    Zaloguj się, aby zobaczyć kod

  • #37 18 Mar 2017 11:42
    tmf
    Moderator Mikrokontrolery Projektowanie

    Tak czytam i oczom niedowierzam. Mamy proste zadanie jakim jest konwersja z bin na bcd w celu wyświetlenia liczby na wyświetlaczu najpewniej 7-segmentowym (w pierwszym poście autor omyłkowo zapewne pisze o 6-segmentowym). Konwersja wykonywana sporadycznie, bo przecież człowiek i tak nie zauważy zmieniającej się np. 1000-razy na wyświetlaczu liczby. Ile razy więc taką konwersję dokonujemy? 10-, 20-razy na sekundę? To i tak aż nadto. I teraz hit - mamy 36 postów o tym jak przyśpieszyć konwersję, która nie ma najmniejszego znaczenia dla szybkości działania i obciążenia mikrokontrolera. Idę o zakład, że autor rozważający marginalne oszczędności, w innej części programu ma miejsca, których optymalizacja da pewnie setki razy większe oszczędności, ale tego nie dostrzega.
    Panowie, zacznijcie pisać programy zamiast skupiać się na bzdurach. O optymalizacji warto myśleć jeśli widzimy, że zbliżamy się do kresu możliwości użytego MCU. Wcześniej - wystarczy tylko poprawnie pisać kod.

  • #38 18 Mar 2017 12:30
    malcompl
    Poziom 9  

    @Wertyuud: O czymś podobnym myślałem, ale się wstrzymywałem po ostatniej wpadce ;)
    Ten Twój kod u mnie zajął około 160-170 cykli (O3, Os), a typowy udivmodsi4 około 600 cykli.

    @tmf: Z praktycznego punktu widzenia to już ustalono, że raczej nie będzie miało to sensu w projekcie autora. Ale jest to dobra zabawa głównie w celach edukacyjnych, bo nudzić może ciągłe tworzenie kodu.

    Może się nieraz to przydać przy analizowaniu binarek, zabezpieczeń, czy innych shittów przy reverse engineeringu, choć raczej nie na tej małej platformie :)

  • #39 19 Mar 2017 14:10
    grko
    Poziom 31  

    @tmf Jakbyś przeczytał cały temat to wiedziałbyś, że wiele osób powtarzało to, że optymalizacje tego typu są bez sensu (w 99% przypadków). Sugerowałem to min ja oraz FCh więc wypadałoby być sprawiedliwym w ocenach postów z tego tematu. Poza tym jeżeli autor nadal chce sobie to optymalizować to nie widzę żadnych przeszkód aby w tym temacie było o tym nawet 1000 postów (w końcu o tym jest ten temat).

  • #40 19 Mar 2017 16:46
    linuxtorpeda
    Poziom 15  

    Wszyscy powtarzają, że optymalizacja jest bez sensu, ale poza paroma osobami nikt nic sensownego nie zaproponował (LUT i double dabble).

    Ja bym przemyślał też, czy nie byłoby sensowne w tym konkretnym przypadku reprezentowanie liczby w formacie BCD, wtedy operacja modulo sprowadzałaby się do założenia odpowiedniej maski na liczbę. Oczywiście, wtedy niektóre pozostałe operacje będą wykonywane dłużej.