Cześć. Mam do Was prośbę. Wytłumaczcie mi coś. Jakie są wady i zalety architektury Von Neumanna w uC ARM np AT91SAM7256. Ostatnio słyszałem o takim stwierdzeniu że ta architektura ma same zalety w pracy uC a porównaniu do architektury Harwardzkiej stosowanej w AVR'ach. Nie było jednak wyjaśnienia tego. Możecie mi wytłumaczyć o co tu chodzi. Ja rozumiem że Von Neumanna to połączenie pamięcie danych i programu w jedną ciągłą ale co mi to daje jako programiście. Przecież pisząc jakiś program w C deklarujemy sobie zmienne i tak za bardzo nie wnikam gdzie ona jest lokowana. Mam zmienną i z niej korzystam. Może jestem trochę laikiem, ale nie za bardzo to rozumiem proszę Was o pomoc w ogarnięciu tego.
Zelety architektury Von Neumannna w uC ARM?
Nov 07, 2009
20 Replies
Nie musi byc ciagla. Ma byc jednolicie adresowana i dostepna.
Korzystasz, bo zmienna z definicji jest w pamieci danych.
A co ze stalymi, np napisami ? Skad printf ma wiedziec ze podany adres odnosi sie do pamieci programu a nie danych ?
W praktyce klopotow nie ma duzo .. no chyba ze przenosisz stary program na harwardzka architekture.
J.
... Akurat tak się składa, że ani ten ARM ani AVR-y nie są klasycznymi przykładami ww architektur. Dodatkowo są to zupełnie różne klasy procesorów, więc ich porównywanie, i to w kontekście architektury, ma niezbyt duży sens. Za to porównywanie z punktu widzenia programisty (C) jest IMHO całkiem ciekawe.
"Prawdziwa" architektura typu Harvard umożliwia jednoczesny dostęp do danych i programu (ze względu na w pełni rozdzielone magistrale). Pozwala to lepiej wykorzystać cykle procesora - w tym samym czasie można pobierać dane do aktualnego rozkazu i następny rozkaz. Oczywiście, aby takie możliwości w pełni wykorzystać procesor musi mieć odpowiednio "sprytny" zestaw rokazów, jednostkę wykonawczą z potokiem (pipeline) i kompilator, który wygeneruje odpowiedni kod.
Architektura von Neumann-a pozwala w założeniu na budowę prostszych procesorów (tylko jedna magistrala). Jednak obserwując ostanie trendy np. w x86, to ta "prostota" gdzieś wyparowała i mamy skompliwany procek, z taką sobie wydajnością (przeliczniki typu liczba operacji/wat lub liczba watów na MHz są raczej kiepskie).
Wydaje się, że w embedded nowsze rozwiązania idą raczej w stronę architektury typu Harvard np. Cortex, MIPS, procesory DSP.
Pozdrawiam,
VN:
a) możliwość wykonywania kodu z RAM, samomodyfikujący sie kod (np dynamiczne ladowanie kodu z karty SD itd).
b) brak osobnych instrukcji dostepu do różnych obszarow pamięci i I/O - tak są skonstruowane współczesne kompilatory jak gcc.
c) w kodzie char* p = "fff" oznacza to samo bez wzgledu na to gdzie fizycznie jest "fff", ten sam kod będzie wysysal dane z RAM i FLASH.
d) możliwośc tworzenia pamięci wirtualnej w standardowy sposób (bo można wykonywac kod w ram).
H:
a) podobno latwiej się implementuje więc tańsze chipy
b) szybsze, bo można w jednym cyklu mieć dwa różne elementy (opcode + dana z ram).
c) dziwaczne kompilatory i/lub workaroundy na istniejace kompilatory
d) przeginanie niektórych w kierunku wesołych koncepcji jak sprzetowe stosy itp co uniemożliwia pracę wielu kompilatorów i w ogóle koncepcji (preemptive multitasking na PICach nie jest chyba możliwy).
Niestety nie. Kompilatory C powstawaly w czasach gdy nie bylo do końca jasne jak odróżnić różne rodzaje pamięci i czy to w ogole potrzebne. Efektem czego co kompilator na embedded to wlasne koncepcje jak okreslić "ten string ma być we Flash, a ten w RAM". Mamy więc mase workaroundów na C.
Duże systemy najczęściej są VN, małe H. Ale cieżko pokazać taką granicę. Sam widzisz ze mały ARM7 jest VN.
slawek7 pisze:
Możesz załadować plik (do pamięci danych) i wykonać go jako program. Taka z gruntu prosta operacja jest kompletnie niemożliwa np. w procesorach AVR z architekturą harwardzką.
Druga sprawa to dostęp do danych - np. w funkcji printf podajesz jako pierwszy parametr adres ciągu znaków do wypisania. No i w ARMach adres to adres - może sobie być w obszarze programu (np. w pamięci Flash), może być w danych. A w AVRach to dopiero jest jazda - wymagane są oddzielne funkcje pobierające ten ciąg z pamięci danych (printf) oraz z pamięci programu (printf_P) i specjalne makra nakazujące umieszczenie ciągu znaków w pamięci programu.
Wiele tych niedogownosci jest gcc-specyficznych, bo gcc nie obsluguje segmentow pamieci - ale ma sie to wkrotce zmienic. Ale ma to tez zalety
- w AVR mozesz miec 64kB FLASH i 64kB SRAM i ciagle adresowac je za pomoca 16-bitowych wskaznikow, co daje istotne zyski, a przy madrze napisanym programie korzystanie z oddzielnych funkcji nie jest az tak uciazliwe. Inaczej musialbys miec wskazniki co najmniej 17 bitowe, czyli w praktyce 24 bitowe, niezly overkill dla procesora, ktory wlasciwie nie ma instrukcji operujacych nawet na 16 bitach. Funkcje tez mozna napisac uniwersalne - ja np. w jednym z programow zdefiniowalem sobie makra, ktore powoduja, ze najstarszy bit adresu interpretowany jest jako wskaznik rodzaju pamieci - jak jest 1 to FLASH,
0 - SRAM, oczywiscie zaweza mi to ilosc obslugiwanej pamieci do 2x32kB, ale mi to wystarczylo. W C++ mozna to zrobic jeszcze bardziej elegancko i transparentnie dla programu.
Ale jak to sobie wyobrazasz ?
No wlasnie.
J.
Join the Discussion
Have something to add? Share your thoughts — no account required.
Didn't find your answer?
Ask the community — no account required