eGospodarka.pl
eGospodarka.pl poleca

eGospodarka.plGrupypl.misc.elektronika › C++ ośla łączka
Ilość wypowiedzi w tym wątku: 91

  • 21. Data: 2023-02-14 22:22:33
    Temat: Re: C++ ośla łączka
    Od: Piotr Gałka <p...@c...pl>

    W dniu 2023-02-14 o 19:06, Janusz pisze:

    >> Do dziś bratu brakuje w C dostępu do bitu przeniesienia, czy parzystości.
    > Nie wiem co w arm-ach jest ale w avr-ch jest rejestr SREG dostępny
    > normalnie z C.
    > Wystarczy z and-ować z odpowiednią maską i mamy np przeniesienie czyli
    > if (SREG & 0x01) {}.
    >

    Prawdopodobnie to ja tu najwięcej i niepotrzebnie mieszam. Wypowiadam
    się w kwestiach, o których nie wiem prawie nic.
    P.G.


  • 22. Data: 2023-02-14 22:42:40
    Temat: Re: C++ ośla łączka
    Od: heby <h...@p...onet.pl>

    On 14/02/2023 15:39, Piotr Gałka wrote:
    > Do dziś bratu brakuje w C dostępu do bitu przeniesienia

    Mała uwaga: standard C w ogóle nie okresla konkretnego sposobu zapisu
    liczb typu integer, dając do wyboru trzy różne.

    Dlatego tego typu funkcjonalnośc musiała by najpierw zabetonować jeden z
    nich (2-complemnet) i określić zachowanie takich bitów w różnych
    operacjach i sekwencach operacji.

    Co prawda ani jeden znany mi kompilator nie potrafi pracować w czymś
    innym niż 2-c, ale standard nie przejmuje się tym, co jest, ale tym, co
    możliwe.

    Są różne koncepcje aby to zabetonować w standardzie, np:

    https://www.open-std.org/jtc1/sc22/wg14/www/docs/n22
    18.htm

    Ogólnie, jeśli chcesz dokonywać operacji na poziomie pojedynczych bitów
    statusowych cpu, to jest ona zależna od konkretnej implementacji
    kompilatora, konkretnego hardware i dostepnych rejestrów.

    Co z grubsza oznacza potrzebę napisania tego w asm.

    I tak powinno być.

    C nie jest od dłubania po bitach na poziomie arytmetyki asemblera,
    ponieważ stabilność bitu przeniesienia może być związana z
    optymalizacjami czy kolejnością wykonywania wyrażeń. To nie ten poziom
    abstrakcji.



  • 23. Data: 2023-02-15 15:40:50
    Temat: Re: C++ ośla łączka
    Od: Piotr Gałka <p...@c...pl>

    W dniu 2023-02-14 o 22:42, heby pisze:

    > Co z grubsza oznacza potrzebę napisania tego w asm.
    >
    > I tak powinno być.
    >
    > C nie jest od dłubania po bitach na poziomie arytmetyki asemblera,
    > ponieważ stabilność bitu przeniesienia może być związana z
    > optymalizacjami czy kolejnością wykonywania wyrażeń.

    Tak jak kompilator wie, że optymalizując nie może zrobić najpierw
    dodawania a potem mnożenia tak mógłby wiedzieć w którym momencie
    wymagane jest wyłuskanie określonego bitu.

    > To nie ten poziom abstrakcji.

    Na pewno masz rację, ale na przykład skorzystanie z bitu parzystości
    uprościło by zapis i przyspieszyło działanie procedury:

    int crc16(byte* buf,int n,int crc)// doliczenie n bajtów bufora
    { // Polynomial = x^16+x^15+x^2+1
    crc&=0xFFFF;
    while(n--)
    {
    int d=((*(buf++))^crc)&0xFF; // lower crc part
    int p=d^(d>>4); p^=p>>2; p^=p>>1; // parity bit
    crc= (crc>>8) ^ (d<<7) ^ (d<<6) ^ ((p&1) ? 0xC001 : 0);
    }
    return crc;
    }

    Kiedyś dawno (w ubiegłym wieku) sprawdzałem, że działa szybciej niż
    standardowy zapis z wewnętrzną pętlą obracania bajtu bit po bicie mimo
    konieczności wieloetapowego uzyskiwania bitu parzystości.
    W assemblerze ma jeszcze większą przewagę nad zapisem z pętlą bo się po
    prostu korzysta z bitu parzystości.

    Wtedy szybkość liczenia crc wydawała nam się ważna. Jak potem doszło
    szyfrowanie i podpisywanie danych w ramce to czas obliczania crc stracił
    na ważności :)

    Jestem prawie pewien, że brat sprawdzał, czy kompilator kompilując na
    8-bitowy procesor się zorientuje, że całą jedną linijkę może pominąć i
    skorzystać z bitu parzystości i prawie na pewno mimo włączonych
    wszystkich optymalizacji nie zorientował się.
    P.G.


  • 24. Data: 2023-02-15 19:50:48
    Temat: Re: C++ ośla łączka
    Od: heby <h...@p...onet.pl>

    On 15/02/2023 15:40, Piotr Gałka wrote:
    >> C nie jest od dłubania po bitach na poziomie arytmetyki asemblera,
    >> ponieważ stabilność bitu przeniesienia może być związana z
    >> optymalizacjami czy kolejnością wykonywania wyrażeń.
    > Tak jak kompilator wie, że optymalizując nie może zrobić najpierw
    > dodawania a potem mnożenia tak mógłby wiedzieć w którym momencie
    > wymagane jest wyłuskanie określonego bitu.

    Programista może być zaskoczony wieloma rzeczami. Czasami jakiś
    statement zostanie usunięty, czasami zmieni się kolejność, czasami
    mnożenie zmieni się na przesuniecie itd itp, w dodatku zależy to od
    flagi -O, dnia tygodnia czy wersji kompilatora.

    Przykładowo: wielu niedzielnych programistów embedded jest zakoczonych,
    że kompialtor może usunąć im jakiś odczyt z rejestru sprzętowego, jeśli
    nie oznaczą go volatile. A to generuje sideeffect, na przykąłd jak
    czytamy bufor typu UART.

    I nagle chcesz odczytywać wewnatrzny status CPU, co do którego nie ma
    nawet pewności, że istnieje na jakiejś architekturze sprzętowej, ani jak
    działa w konkretnym przypadku. To proszenie się o katastrofę. Od tej
    pory C musiał by być *tylko* na procesory z flagą C i to w dodatku
    działającą w jakiś specyficzny sposób. A jak jej nie ma wcale?

    > na przykład skorzystanie z bitu parzystości
    > uprościło by zapis i przyspieszyło działanie procedury:
    > int crc16(byte* buf,int n,int crc)// doliczenie n bajtów bufora
    > {                                 // Polynomial = x^16+x^15+x^2+1
    >   crc&=0xFFFF;
    >   while(n--)
    >   {
    >     int d=((*(buf++))^crc)&0xFF;       // lower crc part
    >     int p=d^(d>>4); p^=p>>2; p^=p>>1;  // parity bit
    >     crc= (crc>>8) ^ (d<<7) ^ (d<<6) ^ ((p&1) ? 0xC001 : 0);
    >   }
    >   return crc;
    > }

    Dlaczego nie chcesz jej napisać w asm, skoro uważasz, że będzie szybsza
    niż wygenerowana przez kompilator?


    > W assemblerze ma jeszcze większą przewagę nad zapisem z pętlą bo się po
    > prostu korzysta z bitu parzystości.

    I dlatego wymagane jest napisanie tego w asm, pod konkretną
    architekturę, ze wszystkimi możliwymi na niej sztuczkami. Kompilatory C
    są znakomite, ale:
    1) programiści embedded często używają jakiejś padliny dostarczonej
    przez producentów niszowych, typu KailC, z lat 80, więc kod produkowany
    ma się nijak do współczesnych sztuczek z optymalizacją, szczególnie z C++.
    2) Jesli C wzbogaciłby się o tak niskopoziomowe detale, znacząco
    ograniczyło by to jego abstrakcje w rozumieniu intencji programisty i
    dużych optymalizacji. Nie chcemy tego, chcemy mieć abstrakcyjny,
    uniwersalny język, a nie język do programowania migania LEDem w 3
    cyklach zegarowych na AVR i niczego innego.
    3) Istnieje wiele rzeczy które w C nie istnieją, na przykład nie ma
    interfejsu do *fence z x86, co powoduje, że wielu ludzi piszących na
    systemy wieloprocesorowe (a więc już embedded) jest zaskoczonych jak
    działa cache w cpu i że to ma to znaczenie. Nie ma supportu *fence, ale
    jest support dla barier, mutexów, lock-free, atomic. Jest to inny poziom
    abstrakcji, przez co nie musisz miec nawet architektury z *fence aby
    pisać kod poprawny, który będzie działać z dowolną architekturą cpu,
    cache itp.

    Najzwyczajniej, mylenie C z asm jest nie na miejscu. To nie ten poziom
    abstrakcji.


  • 25. Data: 2023-02-15 21:28:14
    Temat: Re: C++ ośla łączka
    Od: Piotr Gałka <p...@c...pl>

    W dniu 2023-02-15 o 19:50, heby pisze:

    >> int crc16(byte* buf,int n,int crc)// doliczenie n bajtów bufora
    >> {                                 // Polynomial = x^16+x^15+x^2+1
    >>    crc&=0xFFFF;
    >>    while(n--)
    >>    {
    >>      int d=((*(buf++))^crc)&0xFF;       // lower crc part
    >>      int p=d^(d>>4); p^=p>>2; p^=p>>1;  // parity bit
    >>      crc= (crc>>8) ^ (d<<7) ^ (d<<6) ^ ((p&1) ? 0xC001 : 0);
    >>    }
    >>    return crc;
    >> }
    >
    > Dlaczego nie chcesz jej napisać w asm, skoro uważasz, że będzie szybsza
    > niż wygenerowana przez kompilator?

    Nigdy nic nie pisałem w asm (nawet drobnych wstawek). Mój związek z asm
    jest tylko taki, że napisałem (lata 90-te) makroassembler dla 8051,
    który potem był przez wiele lat używany przez mojego brata (i zapewne
    przez wszystkich używających naszego systemu edukacyjnego DSM-51).

    A to crc16() to jest moja procedura używana w Builderze. Ona powstała z
    przetłumaczenia na C procedury w asm.
    Z ciekawości zapisałem ją też wtedy w sposób klasyczny i porównałem
    (szybkość i czy wyniki faktycznie zawsze wychodzą takie same :) ).
    Ta wyszła szybsza to tamtą usunąłem.

    > Kompilatory C są znakomite, ale:
    > 1) programiści embedded często używają jakiejś padliny dostarczonej
    > przez producentów niszowych, typu KailC, z lat 80, więc kod produkowany
    > ma się nijak do współczesnych sztuczek z optymalizacją, szczególnie z C++.
    > 2) Jesli C wzbogaciłby się o tak niskopoziomowe detale, znacząco
    > ograniczyło by to jego abstrakcje w rozumieniu intencji programisty i
    > dużych optymalizacji. Nie chcemy tego, chcemy mieć abstrakcyjny,
    > uniwersalny język, a nie język do programowania migania LEDem w 3
    > cyklach zegarowych na AVR i niczego innego.
    > 3) Istnieje wiele rzeczy które w C nie istnieją, na przykład nie ma
    > interfejsu do *fence z x86, co powoduje, że wielu ludzi piszących na
    > systemy wieloprocesorowe (a więc już embedded) jest zaskoczonych jak
    > działa cache w cpu i że to ma to znaczenie. Nie ma supportu *fence, ale
    > jest support dla barier, mutexów, lock-free, atomic. Jest to inny poziom
    > abstrakcji, przez co nie musisz miec nawet architektury z *fence aby
    > pisać kod poprawny, który będzie działać z dowolną architekturą cpu,
    > cache itp.
    >
    > Najzwyczajniej, mylenie C z asm jest nie na miejscu. To nie ten poziom
    > abstrakcji.

    Oczywiście masz rację.
    Ja tylko napisałem, że bratu (wychowanemu na asm) brakuje w C czasem
    pewnych rzeczy, ale nie pisałem, że to znaczy, że C powinno je mieć.
    P.G.


  • 26. Data: 2023-02-15 22:14:48
    Temat: Re: C++ ośla łączka
    Od: Marek <f...@f...com>

    On Wed, 15 Feb 2023 19:50:48 +0100, heby <h...@p...onet.pl> wrote:
    > nie oznaczą go volatile. A to generuje sideeffect, na przykąłd jak
    > czytamy bufor typu UART.

    Czyli konkretnie jaki side effect z tym UARTem?

    --
    Marek


  • 27. Data: 2023-02-15 23:10:46
    Temat: Re: C++ ośla łączka
    Od: heby <h...@p...onet.pl>

    On 15/02/2023 22:14, Marek wrote:
    >> nie oznaczą go volatile. A to generuje sideeffect, na przykąłd jak
    >> czytamy bufor typu UART.
    > Czyli konkretnie  jaki side effect z tym UARTem?

    Na przykład, w wielu uartach odczytanie bajtu z bufora wejściowego
    możliwe jest dokładnie *raz* na każdy odebrany bajt, hardware traktuje
    taki odczyt jako procedurę odebrania wiadomości i nastepny odczyt może
    odczytać coś z dalszej pozycji bufora. W ogólnym wypadku, operacja na
    rejestrze *może* spowodować zmianę stanu hardware. Rejestr to nie jest
    pamięć.

    Taka ciekawostka: MC68000 i MC68020 rózniły się tym, że pierwszy w
    niektórych instrukcjach asm zapisywał *dwukrotnie* to samo do pamieci, a
    drugi racz zapisywał a drugi raz odczytywał i w obu wypadkach jedna z
    tych operacji była bez sensu algorytmicznego. To cecha magiczna
    magistrali 6[8|5]00/68000, każdy cykl jest dostępem do pamięci i
    procesor *coś* musi zrobić w każdym cyklu, nawet jak nie miało to sensu,
    bo nie miał co wymienić z pamięcią.

    Był to spory problem, kiedy okazało się, że jeśli ktoś akurat zapisuje
    do rejestru hardwareowego, który ma sideefect np. uruchamiania DMA,
    program działał inaczej w zależności od CPU, mimo że efekt końcowy był
    identyczny z punktu widzenia ASM.

    Ten problem z MC680x0 to sprzętowy odpowiednik "problemów" z C, gdzie
    też pewne operacje mogą pojawić się i zniknąc w wyniku optymalizacji, co
    nie przeszkadza w modelu pamięciowym, ale może powodować katastrofy w
    modelu rejestrów sprzętowych. Dlatego jest słowo volatile. I swoją drogą
    tylko dlatego ;)


  • 28. Data: 2023-02-16 00:02:27
    Temat: Re: C++ ośla łączka
    Od: "Grzegorz Niemirowski" <g...@g...net>

    heby <h...@p...onet.pl> napisał(a):
    > Ten problem z MC680x0 to sprzętowy odpowiednik "problemów" z C, gdzie też
    > pewne operacje mogą pojawić się i zniknąc w wyniku optymalizacji, co nie
    > przeszkadza w modelu pamięciowym, ale może powodować katastrofy w modelu
    > rejestrów sprzętowych. Dlatego jest słowo volatile. I swoją drogą tylko
    > dlatego ;)

    Nie tylko. Także na wypadek modyfikacji zmiennej przez procedurę obsługi
    przerwania. W głównym programie w ramach optymalizacji zmienna może zostać
    skopiowana do rejestru aby obliczenia wykonywać na nim a nie na pamęci. Gdy
    w tym momencie pojawi się przerwanie, zmodyfikowana zostanie stara kopia
    zmiennej.

    --
    Grzegorz Niemirowski
    https://www.grzegorz.net/


  • 29. Data: 2023-02-16 07:22:59
    Temat: Re: C++ ośla łączka
    Od: heby <h...@p...onet.pl>

    On 16/02/2023 00:02, Grzegorz Niemirowski wrote:
    >> w modelu rejestrów sprzętowych. Dlatego jest słowo volatile. I swoją
    >> drogą tylko dlatego ;)
    > Nie tylko. Także na wypadek modyfikacji zmiennej przez procedurę obsługi
    > przerwania.

    Wpadłeś w pułapkę.

    Nie.

    volatile nie służy do tego.

    Do tego, co piszesz, służa bariery/fence.

    > W głównym programie w ramach optymalizacji zmienna może
    > zostać skopiowana do rejestru aby obliczenia wykonywać na nim a nie na
    > pamęci. Gdy w tym momencie pojawi się przerwanie, zmodyfikowana zostanie
    > stara kopia zmiennej.

    Jeśli potraktujesz przerwania jako wątki preemptive, to tak naprawdę
    piszesz o zagadnieniu dostępu do zmiennych przez kilka watków. Tego
    zagadnienia *NIE* należy rozwiązywać za pomocą volatile, ono nie
    powstało do tego i sie do tego NIE nadaje.

    https://stackoverflow.com/questions/4557979/when-to-
    use-volatile-with-multi-threading

    "Short & quick answer: volatile is (nearly) useless for
    platform-agnostic, multithreaded application programming. It does not
    provide any synchronization, it does not create memory fences, nor does
    it ensure the order of execution of operations. It does not make
    operations atomic. It does not make your code magically thread safe.
    volatile may be the single-most misunderstood facility in all of C++."


  • 30. Data: 2023-02-16 12:46:12
    Temat: Re: C++ ośla łączka
    Od: "Grzegorz Niemirowski" <g...@g...net>

    heby <h...@p...onet.pl> napisał(a):
    > Wpadłeś w pułapkę.
    > Nie.
    > volatile nie służy do tego.
    > Do tego, co piszesz, służa bariery/fence.

    Możesz podać przykład na ATmegę?

    > Jeśli potraktujesz przerwania jako wątki preemptive, to tak naprawdę
    > piszesz o zagadnieniu dostępu do zmiennych przez kilka watków. Tego
    > zagadnienia *NIE* należy rozwiązywać za pomocą volatile, ono nie powstało
    > do tego i sie do tego NIE nadaje.

    Wiem. Nic o wątkach nie pisałem.

    --
    Grzegorz Niemirowski
    https://www.grzegorz.net/

strony : 1 . 2 . [ 3 ] . 4 ... 10


Szukaj w grupach

Szukaj w grupach

Eksperci egospodarka.pl

1 1 1

Wpisz nazwę miasta, dla którego chcesz znaleźć jednostkę ZUS.

Wzory dokumentów

Bezpłatne wzory dokumentów i formularzy.
Wyszukaj i pobierz za darmo: