Goto page Previous 1, 2, 3, 4, 5, 6 Next
heby
Guest
Thu Feb 16, 2023 2:54 pm
On 16/02/2023 13:20, Piotr Gałka wrote:
Quote:
Nie widzi żadnego problemu, aby w C dla zmiennych całkowitych było na
przykład pojęcie bitu parzystości. Jak procesor go ma to kompilator
korzysta bezpośrednio, a jak nie ma to wtedy wylicza tak jak ja w tej
crc16().
A do czego to potrzebne przeciętnemu suwerenowi? Z tej samej przyczyny w
C nie ma gotowej funkcji do wygrywania melodyjek na głośniczku podpiętym
pod PB.3. Jest dosłownie 3 osoby na świecie z tą potrzebą.
Dodakowo: jak liczysz parzystość?
Czy -0 i +0 są, czy nie, parzyste? Przypadkowo zakładajmy architekturę
wspierajacą signed-magnitude albo 1-complement. Oba dopuszczalne w C. W
obu występują dwa zera.
Quote:
Gdzie tu proszenie się o katastrofę?
W tym, że standard nie definiuje nawet reprezentacji bitowej liczb.
Skoro tak, to niby jak miałby określać znacznie głębsze detale jak
parzystość, przeniesienie czy cokolwiek detalicznego i związanego z
konkretną architekturą?
Quote:
A....
Nie wspomniałem mu o różnych reprezentacjach zmiennych o których pisałeś
z czego on (tak jak i ja) całkowicie nie zdaje sobie sprawy. Ale
faktycznie są stosowane jakieś inne reprezentacje?
Nie są w praktyce, poza małymi wyjątkami.
Ale standard nie przejmuje się, czy są stosowane, czy nie. Są
dopuszczalne, wiec nie możesz zakładać, że nie mogą istnieć. Standard
nie może ich ignorować.
Quote:
On by potrzebował sizeof(funkcja).
[...]
Quote:
Już opanował wywoływanie funkcji po jej skopiowaniu do RAMu.
Czytaj wątek z przed paru dni:
"MCU - start programu z RAM"
Quote:
Z adresem początku sobie radzi, choć mówi, że wskaźnik na funkcję jest
zawsze większy o 1 od prawdziwego adresu i ustalając fragment do
kopiowania on musi tę jedynkę odejmować.
Wszystko już działa, tylko, że na razie rozmiar funkcji bierze z sufitu
na zapas.
No i jedyne co brakuje do odhaczenia kolejnej funkcjonalności to
ustalenie w jednej funkcji jaki jest sizeof drugiej funkcji.
Może wiesz (lub ktoś inny) jak to się robi.
Było to omawiane w tym wątku. Ogólnie, jesli ma to związek z
programowaniem flasha, to boje się zapytać, czy jakoś się zabezpieczacie
prze utratą zasilania w trakcie.
J.F
Guest
Thu Feb 16, 2023 3:35 pm
On Thu, 16 Feb 2023 13:45:45 +0100, heby wrote:
Quote:
On 16/02/2023 12:46, Grzegorz Niemirowski wrote:
Do tego, co piszesz, służa bariery/fence.
Możesz podać przykład na ATmegę?
Nie. Bo mowa o C ogólnie. Szczególne dla AVR stosujemy sztuczki
asemblerowe, nielegalne w danej sytuacji słowa kluczowe itd itp. Sam
fakt użycia "przerwania" jest z definicji nieistniejącym bytem w C i
wymaga poza-językowych narzędzi, bo sam język nie dostarcza wsparcia dla
przerwań wiec trudno tez, aby dostarczał mechnizmy ich wspierania.
W standardzie jezyka niby nie ma, ale w praktyce czesto jest.
Widac potrzebne, tylko ze realizacja rózna w róznych systemach,
to nie wsadzili do jezyka.
Quote:
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.
Mimo to przerwanie jest czymś identycznym z wątkiem preemptive. Ma te
same konsekwencje i dla dużych procesorów, szczególnie wielordzeniowych,
niesie z sobą dokładnie te same zagrożenia, co wątki. I nie jest tak, że
świat kończy się na 8051. Wielordzeniowe procesory embedded to nic
specjalnie dziwnego.
Wielozadaniowosc tez była różna w wielu systemach.
Stad i "nakładki" na języki.
Quote:
Tam, wszyscy programiści od volatile, wybiją sobie zęby o protokoły
synchronizacji cache, out-of-order execution itd itp.
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.
Przeciez to nie tylko C ma ten problem.
Wiec jesli są rozwiązania dobre, to mozna je w i C zaimplementowac.
Tylko ... schowac pod volatile, czy osobno.
Bo problemow w zaawansowanych systemach istotnie coraz wiecej.
J.
Grzegorz Niemirowski
Guest
Thu Feb 16, 2023 4:23 pm
heby <heby@poczta.onet.pl> napisał(a):
Quote:
Tam, wszyscy programiści od volatile, wybiją sobie zęby o protokoły
synchronizacji cache, out-of-order execution itd itp.
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ą. Powszechnie problem ten rozwiązuje się stosując
volatile.
Quote:
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).
Quote:
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.
Quote:
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? Nie podałeś żadnego argumentu
przeciw volatile. Cały czas chodzi o programy bare metal, bez schedulera.
volatile jest powszechnie stosowanym oraz polecanym rozwiązaniem problemu
optymalizacji na MCU, o którym wspomniałem poprzednio, a doprecyzowałem na
początku tego posta, żeby było jasne o co chodzi. I jakoś w Internecie nie
widzę polemiki z tym polecaniem volatile, z wyjątkiem Twoim postów. Pomijam
oczywiście przypadki używania volatile do innych problemów, do których się
nie nadaje, jak atomowość.
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. 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.
--
Grzegorz Niemirowski
https://www.grzegorz.net/
Piotr GaĹka
Guest
Thu Feb 16, 2023 4:33 pm
W dniu 2023-02-16 o 13:54, heby pisze:
Quote:
Już opanował wywoływanie funkcji po jej skopiowaniu do RAMu.
Czytaj wątek z przed paru dni:
"MCU - start programu z RAM"
Przesłałem bratu (on nie czyta Usenetu) wszystkie wiadomości z tamtego
wątku.
W czasie jak pisałem dalszą część tej wiadomości wstępnie powiedział, że
według niego nie ma tam tego co on szuka. Ale rozmawialiśmy tylko
zgrubnie (ja siedzę w swoim pokoju a on piętro niżej). Coś mówił o
sekcjach, ale że to... coś tam (nie dosłyszałem).
Też rzucę okiem, tylko, że tak właściwie nie mam na to czasu.
Quote:
Było to omawiane w tym wątku. Ogólnie, jesli ma to związek z
programowaniem flasha, to boje się zapytać, czy jakoś się zabezpieczacie
prze utratą zasilania w trakcie.
Chyba powinien się obrazić :)
Napisałeś tak, jakby przeprogramowywanie flasha było jakąś nadzwyczajną
czynnością, a to przecież chyba wszyscy robią.
Są jeszcze jakieś urządzenia bez upgrade?
Do tej pory używaliśmy AtXmega z EEROMem na pokładzie. O ile się
zorientowaliśmy to w ARM (które chyba dużo ludzi używa) EEPROM to jakaś
egzotyka. Stosowana jest emulacja EEPROM we flashu więc wszyscy, którzy
chcą EEPROMu wewnątrz procka muszą programować Flasha.
Od czasu jak tylko przenieśliśmy się z procesorów OTP na flash (jak
pojawiły się pierwsze Atmele) jesteśmy moim zdaniem dobrze zabezpieczeni.
Pierwsza linia obrony:
Nasze urządzenia zasilane są z zasilaczy z podtrzymaniem bateryjnym
(starczającym na kilka godzin). Dopóki nie ma tak długich przerw w
zasilaniu to zanik napięcia zasilania urządzenia praktycznie nie zdarza
się przez lata.
Druga linia obrony:
Jest czujnik napięcia na elektrolicie przed stabilizatorem VCC.
Od przerwania z tego czujnika do choćby drgnięcia w dół napięcia VCC
mija więcej czasu niż flash potrzebuje na dokończenie rozpoczętego
procesu programowania, czy kasowania strony - czyli (pod warunkiem, że
procesor po tym przerwaniu wyłączy wszelkie zbędne obciążenia) każda
rozpoczęta operacja na flashu zostanie dokończona w komfortowych
warunkach. Oczywiście po tym NMI następna operacja nie zostanie rozpoczęta.
To zabezpieczenie występuje tylko w urządzeniach, które przechowują we
flashu jakieś dane. Na przykład nie ma go w czytnikach RFID. Tam
uważamy, że pozostałe zabezpieczenia wystarczą bo tam chodzi tylko o
upgrade, a on się skutecznie broni sam.
Trzecia linia obrony:
Brown-out, który zadziała po tym wszystkim zabezpiecza przed zgłupieniem
procesora, który mógłby wtedy coś nabruździć we flashu.
Różne inne zabezpieczenia, którym trudno nadać kolejne numery:
- ważne informacje we flashu mają sumy kontrolne. Po resecie procesor je
sprawdza. Jak się nie zgadza to przyjmuje bezpieczne wartości default.
- informacja o każdym resecie trafia do rejestracji i serwer może po
resecie skontrolować całą zawartość urządzenia.
- produkujemy urządzenia przez 'upgrade' z programu testowego to
oznacza, że w każdym urządzeniu są praktycznie dwie kopie programu.
- po resecie bootloader sprawdza crc32 programu i jak jest błędne to
sprawdza crc32 upgrade'u i ewentualnie wykonuje upgrade.
- przesyłanie upgrade'u nie niszczy programu (on nadal normalnie działa)
więc przerwanie przesyłania upgrade'u w dowolnym momencie nie jest
problemem,
- dopiero jak przyjdą wszystkie strony upgrade'u jest sprawdzany jego
podpis i upgrade jest wykonywany - zakładamy, że jakby upgrade został
przerwany w tym trakcie to po resecie crc32 to wykryje i upgrade
rozpocznie się od nowa (nie przesyłanie a wykonywanie).
Dotychczas nie zauważyliśmy problemu, którego źródłem byłoby
niedokończenie zapisu flasha.
P.G.
J.F
Guest
Thu Feb 16, 2023 4:37 pm
On Thu, 16 Feb 2023 13:20:42 +0100, Piotr Gałka wrote:
Quote:
A teraz pytanie brata na które nie znamy odpowiedzi.
Ogólnie to jest pierwsze podejście do procesorów ARM (nie wiem z którym
w tej chwili walczy (Silabs EFM32PG22..., EFM32PG23..., a może EFM32TG11..).
Zanim użyje procesor po raz pierwszy musi opanować podstawowe działania
no i jest właśnie na tym etapie.
On by potrzebował sizeof(funkcja).
I to ma zwrocic rozmiar kodu funkcji, czy rozmiar typu zwracanego
przez funkcję?
Quote:
Ale jak próbuje to zrobić to dostaje 1.
Zasugerowałem, że może jak wstawi etykietę (przypomnieliśmy sobie, że
chyba w C coś takiego jest) na nawiasie zamykającym funkcję to uda się
policzyć różnicę między jej adresem a adresem początku funkcji.
Właśnie mi krzyknął (jego pokój jest piętro niżej), że z zewnątrz
funkcji nie ma dostępu do tej etykiety.
Nie liczylbym na to, ze to zadziała poprawnie.
Ale jak chcecie miec klopoty ... dodajcie do funkcji kolejny argument,
ktory przy wywolaniu zwroci róznice miedzy etykietami.
Albo gdzies zapamieta, bo przeciez typ funkcji moze byc inny.
Quote:
Napiszę do czego mu to potrzebne bo czasem może rozwiązanie głównego
problemu robi się inaczej niż on kombinuje.
Wczoraj wieczorem wspólnie tłumaczyliśmy dwa akapity datasheet, czy
manuala (nie wiem - on mi po prostu podświetlił akapit na ekranie i
chodziło o to jak to rozumiemy).
Tam było, że jak się coś robi z programowaniem flasha z wnętrza programu
to ogólnie nie ma gwarancji, że wszystko się uda. I to zdanie było
ogólne - czyli nawet jak ruszasz inną stronę niż jesteś to może coś nie
zadziałać. Nie napisali co dokładnie, ale skoro może coś się nie udać to
my tego nie chcemy. Napisali, żeby przekopiować odpowiednią funkcję do
RAMu, wywołać ją i z niej uruchomić proces kasowania, czy programowania
flasha.
Kopiowanie pod inny adres wymaga relokowalnego kodu - czesto taki
jest, ale warto by sie upewnic.
Quote:
Już opanował wywoływanie funkcji po jej skopiowaniu do RAMu.
Z adresem początku sobie radzi, choć mówi, że wskaźnik na funkcję jest
zawsze większy o 1 od prawdziwego adresu i ustalając fragment do
kopiowania on musi tę jedynkę odejmować.
Ciekawe, bardzo ciekawe.
A niech wywola gdzies funkcje ze wskaznika, i zobaczy jak to sie
skompiluje - tez bedzie cofnięcie o bajt?
Chyba, ze przed punktem startowym funkcji jest cos waznego zapisane.
Quote:
Wszystko już działa, tylko, że na razie rozmiar funkcji bierze z sufitu
na zapas.
No i jedyne co brakuje do odhaczenia kolejnej funkcjonalności to
ustalenie w jednej funkcji jaki jest sizeof drugiej funkcji.
To chyba nie ma.
Napisalbym to w assemblerze, zeby wiadomo bylo, ze nic sie nie sp*,
lub postaral sie skorzystac z jakiejs dynamicznie ladowanej biblioteki
lub pozostal przy zapasie :-)
Quote:
Może wiesz (lub ktoś inny) jak to się robi.
https://developer.arm.com/documentation/ka003803/latest
cos takiego?
:-(
J.
Piotr GaĹka
Guest
Thu Feb 16, 2023 5:05 pm
W dniu 2023-02-16 o 15:37, J.F pisze:
Quote:
On by potrzebował sizeof(funkcja).
I to ma zwrocic rozmiar kodu funkcji, czy rozmiar typu zwracanego
przez funkcję?
Wiedziałem, że w tym miejscu jest niejasne i ze zaraz dalej się wyjaśni.
Quote:
Już opanował wywoływanie funkcji po jej skopiowaniu do RAMu.
Z adresem początku sobie radzi, choć mówi, że wskaźnik na funkcję jest
zawsze większy o 1 od prawdziwego adresu i ustalając fragment do
kopiowania on musi tę jedynkę odejmować.
Ciekawe, bardzo ciekawe.
On dokładnie wie o co chodzi i próbował mi wyjaśnić ale nie do końca
ogarnąłem. To nie jest kwestia błędu kompilatora tylko hardware'u i tak
ma być. Na tyle na ile zrozumiałem to przy operacji wywołania funkcji
(nie na poziomie C tylko na poziomie assemblera) wymagane jest
ustawienie najmłodszego bitu adresu na 1. A że wszystkie funkcje
umieszczane są pod adresami modulo (nie wiem, coś więcej niż 1) to
ustawienie tego bitu na 1 daje adres o 1 większy.
Quote:
Dzięki.
Wygląda na dokładnie jego pytanie.
Na razie nie próbowałem zrozumieć odpowiedzi.
Przesłałem mu. Zobaczymy. Na razie chwilowo go nie ma (chyba poszedł na
obiad, co i ja zaraz zrobię).
P.G.
heby
Guest
Thu Feb 16, 2023 6:56 pm
On 16/02/2023 15:23, Grzegorz Niemirowski wrote:
Quote:
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.
Quote:
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.
Quote:
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.
Quote:
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.
Quote:
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?
Quote:
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?
Quote:
Cały czas chodzi o programy bare metal, bez
schedulera.
Przerwania to multitasking, taki sam jak w schedulerze preemptive.
Quote:
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.
Quote:
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_programming)
[...]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?
Quote:
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.
Quote:
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/volatile-considered-harmful.html
heby
Guest
Thu Feb 16, 2023 7:01 pm
On 16/02/2023 15:33, Piotr Gałka wrote:
Quote:
Napisałeś tak, jakby przeprogramowywanie flasha było jakąś nadzwyczajną
czynnością, a to przecież chyba wszyscy robią.
Niezliczona ilośc błędów popełnianych przez programistów w takim kodzie
każe mi dmuchać na zimne. Taki kod powinien podlegać weryfikacji
formalnej a z drugiej strony "zbrickowanie" urządzeń to rzecz tak
powszechna, że zastanawiam się kto w ogóle pisze te bootloadery,
flashery itd itp. bo wyglądają jak prace zaliczeniowe kiepskich studentów.
Quote:
Dotychczas nie zauważyliśmy problemu, którego źródłem byłoby
niedokończenie zapisu flasha.
Zastanawia mnie wobec tego ta kombinacja z flashowaniem z RAM.
Musicie skasować cały flash (wątpię)? Ma byćszybciej? Coś innego nie działa?
Grzegorz Niemirowski
Guest
Thu Feb 16, 2023 8:11 pm
heby <heby@poczta.onet.pl> napisał(a):
Quote:
Przecież zlinkowałem arykuł, w którym masz jasno wypisane powody i
ostrzeżenie.
I w sumie jako rozwiązanie podają std::atomic. Ciekawe czy atomic z C też
może być.
Quote:
Cały czas chodzi o programy bare metal, bez schedulera.
Przerwania to multitasking, taki sam jak w schedulerze preemptive.
Chodziło o to, że jak jest scheduler to zwykle też masz pod ręką semafory,
kolejki itd.
Quote:
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.
Miałem właśnie na myśli MCU.
Quote:
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_programming)
[...]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?
Ale cały czas mi chodzi o ten problem cache. Wiem dobrze, że volatile nie
rozwiązuje zacytowanych wyżej problemów.
Quote:
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.
Zgadza się. Niemniej dlatego wspomniałem, że problem dotyczy MCU.
Quote:
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.
OK, tutaj zgoda.
Quote:
Dzięki.
--
Grzegorz Niemirowski
https://www.grzegorz.net/
Marek
Guest
Thu Feb 16, 2023 8:22 pm
On Thu, 16 Feb 2023 13:20:42 +0100, Piotr
Gałka<piotr.galka@cutthismicromade.pl> wrote:
Quote:
Tam było, że jak się coś robi z programowaniem flasha z wnętrza
programu
to ogólnie nie ma gwarancji, że wszystko się uda. I to zdanie było
ogólne - czyli nawet jak ruszasz inną stronę niż jesteś to może coś
nie
zadziałać. Nie napisali co dokładnie, ale skoro może coś się nie
udać to
Ciekawe. Nie wiem jak w arm ale w mips setki tysięcy razy
programowałem flash z kodu będącym w innej stronie niż strona
programująca i nigdy nie miałem z tym problemu.
--
Marek
Marek
Guest
Thu Feb 16, 2023 8:27 pm
On Thu, 16 Feb 2023 13:54:54 +0100, heby <heby@poczta.onet.pl> wrote:
Quote:
Było to omawiane w tym wątku. Ogólnie, jesli ma to związek z
programowaniem flasha, to boje się zapytać, czy jakoś się
zabezpieczacie
prze utratą zasilania w trakcie.
A co to za problem? Jak się przerwie programowanie z jakiekolwiek
powodu to bootloader zaprogramuje ponownie po resecie. Jeśli
urządzenie wymaga idiotycznego "nie wyłączaj urządzenia podczas
aktualizacji" to nadaje się do kosza a "twórcom" należą się baty.
--
Marek
heby
Guest
Thu Feb 16, 2023 8:56 pm
On 16/02/2023 19:11, Grzegorz Niemirowski wrote:
Quote:
Przecież zlinkowałem arykuł, w którym masz jasno wypisane powody i
ostrzeżenie.
I w sumie jako rozwiązanie podają std::atomic. Ciekawe czy atomic z C
też może być.
A co broni użyć C++, szczególnie na nowej arch? Nawet na AVR to zmiana 2
literek na dwa + w nazwie kompilatora i strata bodaj 4 bajtów na
dodatkową sekcję, którą można łatwo usunąć, jak ktoś sępi. Więc na arch,
gdzie atomic ma implementację, to powinno kosztować asymptotyczne zero.
Quote:
Cały czas chodzi o programy bare metal, bez schedulera.
Przerwania to multitasking, taki sam jak w schedulerze preemptive.
Chodziło o to, że jak jest scheduler to zwykle też masz pod ręką
semafory, kolejki itd.
Ich istnienie jest rozdzielne. Do tego stopnia, że trafiłem kiedyś na
urządzenie o nazwie "Tiger" zawierajace "TigerBASIC", taki panel do
kontroli automatyki, z wyświetlaczem graficznym. Gdzie rozdział
poświęcony miltithread miał opis 1 funkcji tworzącej wątek i kończył się
na "należy zwrócić uwagę na dostępie do zmiennych w innych wątkach". I
wsio na temat synchronizacji.
Quote:
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.
Miałem właśnie na myśli MCU.
A ja wskazuje, że granica między dużym systemem i uC/MCU zaciera się
coraz szybciej. Mam przed sobą pdf dwurdzeniowego ARM za normalne $. Do
migania diodą nadaje się tak samo jak AVR. Może nawet konsumuje mniej
energii, nie zdzwiłbym się.
Quote:
Niezliczona ilość postów/stron wyjasnia, dlaczego volatile nie jest
tym, o czym myślisz, że do czego jest.
Serio, nie zauważyłes?
Ale cały czas mi chodzi o ten problem cache. Wiem dobrze, że volatile
nie rozwiązuje zacytowanych wyżej problemów.
volatile źle rozwiązuje równiez "ten problem z cache" w sensie
optymalizacji. Bo zabrania *zawsze* optymalizacji danej zmiennej,a nie
tylko w miejscu, gdzie jest błędem logicznym.
Quote:
Zgadza się. Niemniej dlatego wspomniałem, że problem dotyczy MCU.
MCU za chwile będą takie jak duże systemy. Duże systemy idą w szerokość
(ilośc rdzeni) to samo czeka uC. Prawdę mówiąc bardzo mi szkoda, że
Parallax Propeller nie dał rady stać się popularnym, to był bardzo
interesujacy CPU do aplikacji real-time.
heby
Guest
Thu Feb 16, 2023 8:57 pm
On 16/02/2023 19:27, Marek wrote:
Quote:
Było to omawiane w tym wątku. Ogólnie, jesli ma to związek z
programowaniem flasha, to boje się zapytać, czy jakoś się
zabezpieczacie prze utratą zasilania w trakcie.
A co to za problem? Jak się przerwie programowanie z jakiekolwiek powodu
to bootloader zaprogramuje ponownie po resecie. Jeśli urządzenie wymaga
idiotycznego "nie wyłączaj urządzenia podczas aktualizacji" to nadaje
się do kosza a "twórcom" należą się baty.
Czyli sporej częsci urządzeń wyświetlajacych ten komunikat. Ja bym
zaczął od Windowsa. Co prawda to nie flash, ale w sumie co za różnica.
JDX
Guest
Fri Feb 17, 2023 3:28 am
JDX
Guest
Fri Feb 17, 2023 3:35 am
Goto page Previous 1, 2, 3, 4, 5, 6 Next