Czytałem o arduino i architekturze AVR i utknąłem w punkcie, w jaki sposób rozwiązuje się problem przeciągania lub propagacji rurociągów przez wprowadzenie architektury Harvard w AVR. To znaczy, że Harvard zapewnia po prostu inną lokalizację przechowywania niż pamięć danych i pamięć programu, które umożliwia załadowanie programu bez operatora. Ale jak to pomaga rozwiązać powyższy problem?
13
Odpowiedzi:
Architektura Harvarda, która, nawiasem mówiąc, była używana na długo przed wynalezieniem AVR, rzeczywiście ma osobne przestrzenie adresowe dla pamięci programu i pamięci danych. Przynosi to imprezie możliwość zaprojektowania obwodu w taki sposób, aby osobna magistrala i obwód sterujący mogły być użyte do obsługi przepływu informacji z pamięci programu i przepływu informacji do pamięci danych. Zastosowanie oddzielnych magistral oznacza, że pobieranie i wykonywanie programu może być kontynuowane bez przerywania od czasu do czasu transferu danych do pamięci danych. Na przykład w najprostszej wersji architektury moduł pobierania programu może być zajęty pobieraniem następnej instrukcji w sekwencji programu równolegle z operacją przesyłania danych, która mogła być częścią poprzedniej instrukcji programu.
Na tym najprostszym poziomie architektura Harvarda ma takie ograniczenie, że generalnie nie jest możliwe umieszczenie kodu programu w pamięci danych i wykonanie go stamtąd.
Istnieje wiele odmian i złożoności, które można dodać do tej najprostszej formy architektury, którą opisałem. Jednym z powszechnych dodatków jest dodawanie buforowania instrukcji do magistrali informacji o programie, która umożliwia jednostce wykonującej instrukcje szybszy dostęp do następnego kroku programu bez konieczności przechodzenia do wolniejszej pamięci w celu pobrania kroku programu za każdym razem, gdy jest to wymagane.
źródło
Niektóre uwagi oprócz odpowiedzi Michaelsa:
1) architektura Harvarda nie wymaga, aby istniały dwie oddzielne przestrzenie dla danych i kodu, tylko, że są (przeważnie) pobierane przez dwie różne magistrale .
2) problemem rozwiązanym przez architekturę Harvarda jest rywalizacja magistrali: w systemie, w którym pamięć kodu może prawie wystarczająco szybko dostarczyć instrukcje, aby procesor działał na pełnych obrotach, dodatkowe obciążenie związane z pobieraniem / przechowywaniem danych spowalnia procesor na dół. Ten problem rozwiązuje architektura Hardvard: pamięć, która jest (trochę) za wolna dla szybkości procesora.
Pamiętaj, że buforowanie to kolejny sposób rozwiązania tego problemu. Często Harvarding i buforowanie są używane w interesujących kombinacjach.
Harvard korzysta z dwóch autobusów. Nie ma nieodłącznego powodu, aby trzymać się dwóch, w bardzo szczególnych przypadkach stosuje się więcej niż dwa, głównie w procesorach DSP (procesorach sygnałowych).
Bankowość pamięci (w sensie rozdzielania dostępu do pamięci do różnych zestawów układów) może być postrzegana jako swego rodzaju Harvarding w samym systemie pamięci, nie na podstawie rozróżnienia danych / kodu, ale na niektórych bitach adresu.
źródło
Czysta architektura Harvarda ogólnie pozwala komputerowi o danym poziomie złożoności działać szybciej niż architektura Von Neumana, pod warunkiem, że nie trzeba współużytkować zasobów między kodem a pamięcią danych. Jeśli ograniczenia wyprowadzeń lub inne czynniki zmuszają użycie jednej magistrali do uzyskania dostępu do obu przestrzeni pamięci, zalety takie mogą zostać w dużej mierze zniesione.
„Czysta” architektura Harvarda będzie ograniczona do działającego kodu, który jest wprowadzany do pamięci przez inny mechanizm niż procesor, który uruchomi kod. Ogranicza to użyteczność takich architektur dla urządzeń, których przeznaczenie nie jest ustawione przez fabrykę (lub kogoś ze specjalistycznym sprzętem do programowania). Aby rozwiązać ten problem, można zastosować dwa podejścia:
Niektóre systemy mają oddzielne obszary kodu i pamięci, ale zapewniają specjalny sprzęt, który można poprosić o krótkotrwałe przejęcie magistrali kodowej, wykonanie pewnych operacji i zwrot kontroli do CPU po zakończeniu takiej operacji. Niektóre takie systemy wymagają dość skomplikowanego protokołu do przeprowadzenia takich operacji, niektóre mają specjalne instrukcje, aby wykonać takie zadanie, a niektóre nawet szukają określonych adresów „pamięci danych” i wyzwalają przejęcie / zwolnienie, gdy próbuje się uzyskać do nich dostęp . Kluczowym aspektem takich systemów jest to, że istnieją wyraźnie zdefiniowane obszary pamięci dla „kodu” i „danych”; nawet jeśli procesor może odczytywać i zapisywać przestrzeń „kodu”, nadal jest rozpoznawany jako semantycznie różny od przestrzeni danych ”.
Alternatywnym podejściem stosowanym w niektórych systemach wyższej klasy jest posiadanie kontrolera z dwiema magistralami pamięci, jedną dla kodu i jedną dla danych, oba połączone z jednostką arbitrażu pamięci. Ta jednostka z kolei jest podłączona do różnych podsystemów pamięci za pomocą osobnej magistrali pamięci dla każdego. Dostęp do kodu do jednego podsystemu pamięci może być przetwarzany jednocześnie z dostępem do danych do innego; tylko jeśli kod i dane spróbują uzyskać dostęp do tego samego podsystemu jednocześnie, jedno z nich będzie musiało poczekać.
W systemach, które stosują to podejście, niekrytyczne pod względem wydajności części programu mogą po prostu zignorować granice między podsystemami pamięci. Jeśli kod i dane znajdują się w tym samym podsystemie pamięci, rzeczy nie będą działały tak szybko, jak gdyby były w oddzielnych podsystemach, ale dla wielu części typowego programu, które nie będą miały znaczenia. W typowym systemie będzie mała część kodu, w której wydajność naprawdę ma znaczenie, i będzie działać tylko na niewielkiej części danych przechowywanych przez system. Gdyby ktoś miał system z 16 KB pamięci RAM, który był podzielony na dwie partycje 8 KB, można by użyć instrukcji linkera, aby upewnić się, że kod krytyczny dla wydajności znajduje się w pobliżu początku całej przestrzeni pamięci, a dane krytyczne dla wydajności były blisko koniec. Jeśli ogólny rozmiar kodu wzrośnie do np. 9 KB, kod z ostatniego 1K działałby wolniej niż kod umieszczony gdzie indziej, ale kod ten nie byłby krytyczny pod względem wydajności. Podobnie, jeśli kod miałby np. Tylko 6 KB, ale dane wzrosłyby do 9 KB, dostęp do najniższego 1 000 danych byłby powolny, ale gdyby dane o kluczowej wydajności były zlokalizowane gdzie indziej, nie stanowiłoby to problemu.
Zauważ, że chociaż wydajność byłaby optymalna, gdyby kod był mniejszy niż 8 KB, a dane poniżej 8 KB, wspomniana konstrukcja systemu pamięci nie narzucałaby żadnej ścisłej podziału między kodem a przestrzenią danych. Jeśli program potrzebuje tylko 1 KB danych, kod może wzrosnąć do 15 KB. Jeśli potrzebuje tylko 2K kodu, dane mogą wzrosnąć do 14K. Znacznie bardziej wszechstronny niż posiadanie obszaru 8K tylko dla kodu i obszaru 8K tylko dla danych.
źródło
Jednym z aspektów, które nie zostały omówione, jest to, że w przypadku małych mikrokontrolerów, zwykle z tylko 16-bitową magistralą adresową, architektura Harvarda skutecznie podwaja (lub trzykrotnie) przestrzeń adresową. Możesz mieć 64 KB kodu, 64 KB pamięci RAM i 64 KB We / Wy odwzorowanych w pamięci (jeśli system używa We / Wy odwzorowanych w pamięci zamiast numerów portów, ten ostatni już oddziela adresowanie We / Wy od kodu & Przestrzenie pamięci RAM).
W przeciwnym razie musisz wcisnąć kod, pamięć RAM i opcjonalnie adres I / O w tej samej przestrzeni adresowej 64K.
źródło