Zelety architektury Von Neumannna w uC ARM?

Nov 07, 2009 20 Replies

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.


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