eGospodarka.pl
eGospodarka.pl poleca

eGospodarka.plGrupypl.misc.elektronikaC++ ośla łączka › Re: C++ ośla łączka
  • Path: news-archive.icm.edu.pl!news.icm.edu.pl!newsfeed.pionier.net.pl!2.eu.feeder.erj
    e.net!feeder.erje.net!weretis.net!feeder8.news.weretis.net!eternal-september.or
    g!reader01.eternal-september.org!.POSTED!not-for-mail
    From: heby <h...@p...onet.pl>
    Newsgroups: pl.misc.elektronika
    Subject: Re: C++ ośla łączka
    Date: Thu, 16 Feb 2023 17:56:15 +0100
    Organization: A noiseless patient Spider
    Lines: 169
    Message-ID: <tsln7m$3a7hn$1@dont-email.me>
    References: <16qbnwht7z74n.8802zax2iioq$.dlg@40tude.net>
    <63dad430$0$9589$65785112@news.neostrada.pl>
    <trelrs$g0p$1$Janusz@news.chmurka.net>
    <trgbkf$st9$1$PiotrGalka@news.chmurka.net>
    <63dbd22e$0$9601$65785112@news.neostrada.pl>
    <ts6rps$roo$1$PiotrGalka@news.chmurka.net>
    <63e9f424$0$19625$65785112@news.neostrada.pl>
    <tsg6eb$96a$1$PiotrGalka@news.chmurka.net> <tsgv8m$2kn8s$1@dont-email.me>
    <tsiqth$55n$1$PiotrGalka@news.chmurka.net> <tsj9if$2v62r$1@dont-email.me>
    <a...@n...neostrada.pl>
    <tsjl9d$30gq5$1@dont-email.me>
    <63ed6483$0$9597$65785112@news.neostrada.pl>
    <tski4a$365ef$1@dont-email.me>
    <63ee1784$0$9589$65785112@news.neostrada.pl>
    <tsl8hv$38gns$1@dont-email.me>
    <63ee3c75$0$19611$65785112@news.neostrada.pl>
    MIME-Version: 1.0
    Content-Type: text/plain; charset=UTF-8; format=flowed
    Content-Transfer-Encoding: 8bit
    Injection-Date: Thu, 16 Feb 2023 16:56:22 -0000 (UTC)
    Injection-Info: reader01.eternal-september.org;
    posting-host="6753f9a9e6e28e5f7a0b71608edb3765";
    logging-data="3481143";
    mail-complaints-to="a...@e...org";
    posting-account="U2FsdGVkX19jk3APcZrlYNjTaz5l1pYv"
    User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:102.0) Gecko/20100101
    Thunderbird/102.7.2
    Cancel-Lock: sha1:+vvebq8yOoktV+SZeBzWqHv5Ugc=
    In-Reply-To: <63ee3c75$0$19611$65785112@news.neostrada.pl>
    Content-Language: en-US
    Xref: news-archive.icm.edu.pl pl.misc.elektronika:778372
    [ ukryj 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: