eGospodarka.pl
eGospodarka.pl poleca

eGospodarka.plGrupypl.misc.elektronikaC++ ośla łączkaRe: C++ ośla łączka
  • Data: 2023-02-16 17:56:15
    Temat: Re: C++ ośla łączka
    Od: heby <h...@p...onet.pl> szukaj wiadomości tego autora
    [ pokaż wszystkie nagłówki ]

    On 16/02/2023 15:23, Grzegorz Niemirowski wrote:
    > Ale ja nic nie mówiłem o cache procesora ani kolejności operacji. Chodzi
    > o problem jaki wprowadza kompilator optymalizując dostęp do zmiennej
    > poprzez przeniesienie jej z RAM-u do rejestru w jakimś fragmencie kodu.
    > Żadne bariery na to nie pomogą.

    Istnieje wiele metod, które pozwalają dostać co chcesz bez udziału volatile.

    Mutexy, external function, sekcje krytyczne, atomiki, interlocked itd itp.

    > Powszechnie problem ten rozwiązuje się
    > stosując volatile.

    Nie. Powszechnie rozwiązuje się ten problem używając poprawnych wzorców
    projektowych dostępnych w języku i czasami na danej platformie
    kompilatora bądź hardware.

    Używanie volatile w tym celu pochodzi z czasów, kiedy nie było innych metod.

    Volatile jest np. bezsensowne, bo uniemożliwia optymalizacje w
    miejscach, gdzie jej nie chcesz i niestety również tam, gdzie chcesz.
    Albo wszystko albo nic.

    Na chwile obecną volatile uzyteczne jest tylko przy komunikacji z
    hardware *oraz* na wyjątkowo zapuszczonych architekturach, gdzie
    dokłądnie wiesz, co się stanie po jego użyciu.

    Przykładowo, na 8051 przy jednoczesnym dostępie do RAMu bajtowo i
    bitowo, biedy kompilator może źle wyoptymalizować kawałek kodu. Ale to
    akuratnie taka popieprzona architektura, do której C pasuje w sposób
    wymagający wbijania go młotkiem, trudo się więc dziwić, że wymaga
    również przedziwacznych konstrukcji prostujących ten C do czegoś
    użytecznego na guano 8051.

    >> Uwaga o volatile dotyczy *języka* C a nie implementacji tego na AVR.
    > To nie musi być AVR. Wspomniałem o nim, bo on nawet nie ma operacji do
    > barier jak np. ARM (DSB, DMB, ISB).

    Więc wyraźnie wyjaśniam, że jeśli chodzi o ogólne uzycie volatile, to
    jest ono bezsensowne do rzeczy innych niż pamięć rejetrowa urządzeń. Ale
    w szczególności, w programach do migania diodą na AVR, może być w jakimś
    stopniu emulacją brakującej funkcjonalności i tam stosując je rozważnie
    da się dostać namiastkę poprawnej synchronizacji.

    >> Sam fakt użycia "przerwania" jest z definicji nieistniejącym bytem w C
    > Kogo to obchodzi? Jak na złość w prawie każdym procesorze są przerwania.

    Które obsługiwane są przez skrajnie specyficzny kod, zazwyczaj niezgodny
    z ABI kompilatora, wymagajacy workaroudów typu pre/post i naked. To, że
    procedure przerwania można napisać w C nie oznacza, że to "normalne" C.
    To wyjątkowo wyjątkowe kodowanie, zazwyczaj na poziomie OSa, którego
    zwykłego kodera C nie dotyczy.

    User na górze, nawet jeśli wołany jest z wnętrza przerwania, nie widzi
    róznicy między nim a wątkiem. Katastrofy z volatile i weak memory
    ordering sa jak najbardziej możliwe, im wyżej w komplikacji procesora
    wylądujesz ze swoim kodem.

    >> PS. Zaznaczam, że nic nie pisałeś o AVR w poprzednim poście, wiec w
    >> ogólnym wypadku, volatile nie może i nie powinno być uzywane w celu
    >> synchronizacji zmiannych w przerwaniach. W szczególnym, kiedy znasz
    >> konkretną architekturę, być może.
    > A dlaczego nie powinno i co polecasz w zamian?

    Atomik? Mutex? Sekcja krytyczna? IPC?

    > Nie podałeś żadnego
    > argumentu przeciw volatile.

    Przecież zlinkowałem arykuł, w którym masz jasno wypisane powody i
    ostrzeżenie.

    Volatile działa inaczej, niż mysli 95% programistów C. I o ile w małych
    systemach z AVRkiem to akurat nie problem, co najwyżej przyczyna
    marudzenia "panie, jakie te kompialtory złe robio, nawet zopymalizować
    nie potrafio", to w dużych systemach prowadzi prosto do wybicia sobie
    zębów. A te "duże systemy" to obecnie coś, co dobija się z hukiem do
    drzwi embedowców. Czasy 8051, po raz kolejny, jak co roku od 40 lat,
    minęły. Za chwile powszechne będą RISC-V z kilkoma rdzeniami, w
    zależnosci od wymogów mocowych, ze złożonymi superskalarnymi potokami i
    pokręconym cache. Dalej będziesz w nich stosował volatile?

    > Cały czas chodzi o programy bare metal, bez
    > schedulera.

    Przerwania to multitasking, taki sam jak w schedulerze preemptive.

    > volatile jest powszechnie stosowanym oraz polecanym
    > rozwiązaniem problemu optymalizacji na MCU

    W pierdołowatych małych cpu zapewne tak. W dużych absolutnie nie. Pisząc
    relatywnie duże programy, o dużej złożoności, z masą wątków i wymianą
    danych między nimi, nie miałem okazji użyć volatile ani razu. Z
    ciekawostek: w poważnych firmach słowo volatile jest wyłapywane przez
    linter kodu i wymaga zgody komisji za zielonym suknem.

    > I jakoś w Internecie nie widzę polemiki z tym polecaniem
    > volatile

    Bo jej nie szukasz. Google aż krzyczy "nie uzywaj volatile, to nie
    działa jak myślisz".

    Choćby wiki:

    https://en.wikipedia.org/wiki/Volatile_(computer_pro
    gramming)

    [...]Furthermore, in C and C++ it does not work in most threading
    scenarios, and that use is discouraged.[...]"

    "[...]Operations on volatile variables are not atomic, nor do they
    establish a proper happens-before relationship for threading. This is
    specified in the relevant standards (C, C++, POSIX, WIN32),[1] and
    volatile variables are not threadsafe in the vast majority of current
    implementations. Thus, the usage of volatile keyword as a portable
    synchronization mechanism is discouraged by many C/C++ groups[...]".

    Niezliczona ilość postów/stron wyjasnia, dlaczego volatile nie jest tym,
    o czym myślisz, że do czego jest.

    Serio, nie zauważyłes?

    > Więc mamy kod:
    > int z = 0;
    > int main() {
    >    while(!z);
    >    return 0;
    > }
    > isr_handler() {
    >    z = 1;
    > }
    > Przy kompilacji z -O0 nie ma problemu, przerwanie przerwie pętlę while.
    > Przy wyższej optymalizacji pętla może czytać kopię zmiennej i przez to
    > nie zauważyć jej modyfikacji. volatile łatwo i szybko usuwa ten problem.

    W małym procesorze tak.

    Teraz weź duży procesor. Być może Ci zaskoczy, że jeśli to przerwanie to
    inny wątek na innym rdzeniu, to mimo, że rdzeń zapisze z = 1, to pętla
    nigdy się nie zakończy. Bo możesz mieć system ze słabą koherencją cache
    i bez bariery/fence informacja nigdy nie zostanie zsynchronizowana z
    lokalnymi cache obu rdzeni. Albo ciekawoski z przestawianiem zapisów,
    kiedy jeden rdzeń widzi zapis w innej kolejnosci niż wykonany w
    sąsiednim rdzeniu.

    Swoją drogą ten problem jest trudny do zauważenia przez przeciętnego
    wciskacza klawiszy, bo x86 jest wyjątkowo tolerancyjny dla dziadowskiego
    kodu. Tam to działa przypadkiem i wiele osób ma podejrzenie, że nie bez
    powodu takie decyzje projektowe podjęto: łatwiej było zaprojektować
    tolerancyjny procesor niż liczyć na poprawianie miliardów lini kodu po
    kiepskich programistach.

    > Mam nadzieję, że teraz już jest wszystko jasne i w końcu dowiem się
    > jakie straszne efekty spowoduje tutaj wprowadzenie volatile oraz co jest
    > lepszego.

    Powoduje: zablokowanie optymalizacji *całej* zmiennej, wszędzie oraz nie
    usuwa innych problemów z wątkowością, takich jak weak memory ordering
    czy synchronizacja cache.

    Ogólnie działa tylko na małych systemach, gdzie nie ma tego typu
    zagrożeń, co powoduje że volatile jest narzędziem workaroudującym
    prawidłowe metody, a nie metodą samą w sobie.

    Na większych sens jest zerowy, poza dostępem do rejestrów.

    Jak już musisz mieć niskopoziomowo to wyjasnione, to może zerknij tutaj:

    https://www.kernel.org/doc/html/latest/process/volat
    ile-considered-harmful.html

Podziel się

Poleć ten post znajomemu poleć

Wydrukuj ten post drukuj


Następne wpisy z tego wątku

Najnowsze wątki z tej grupy


Najnowsze wątki

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: