Jest tu kilka różnych kompromisów.
Po pierwsze, chcemy, aby instrukcje miały stałą szerokość (32 bity). Gwarantuje to, że instrukcje są blokowane w pamięci podręcznej i wyrównane do strony, co upraszcza pamięć podręczną i obecność strony oraz kontrolę uprawnień.
Po drugie, chcemy, aby różne pola instrukcji ( opcode
/ source regs
/ immediates
) miały stałą szerokość i stałą pozycję. To sprawia, że dekodują je szybciej / mniej logicznie i są potrzebne na wczesnych etapach procesu. ( destination
Rejestr nie jest potrzebny do końca potoku, więc może znajdować się w różnych miejscach R
i I
instrukcjach.) Pozycja i szerokość function
pola mają znaczenie mniej ważne, ponieważ to musi kontrolować funkcję ALU, ale to jest w trzecim etapie rurociągu, więc masz trochę czasu, aby z nim popracować w razie potrzeby.
I
J
J
2)282)28I
instrukcje są również przydatne dla autorów kompilatorów / linkerów. (Na SPARC, gdzie bezpośrednie pole miało tylko 12 bitów, musieli dodać całą specjalną load-high
klasę instrukcji z 20-bitowym natychmiastowym.)
2)6= 64J
R
I
Ale to pozostawia trochę poruszenia z R
instrukcjami. Oprócz 6-bitowego kodu operacyjnego, potrzebują one tylko 15 dodatkowych bitów do specyfikacji rejestru, co pozostawia 11 bitów dla rozszerzonego kodu operacji i / lub kwoty przesunięcia.
Powinieneś pomyśleć o function
polu jako o rozszerzonym kodzie operacji dla R
instrukcji. Jest tylko jeden R
kod functions
operacji R
instrukcji , ale są 64 różne, które instrukcja może wykonać.
W porządku. Mamy 60 różnych I
instrukcji i 64 różnych R
instrukcji, więc gdzie powinniśmy umieścić instrukcje natychmiastowej zmiany?
Cóż, nie tylko jest mniej I
instrukcji, ale jest o wiele więcej rzeczy, które chcemy zrobić z I
instrukcjami. Przypomnij sobie, że wszystkie instrukcje gałęzi muszą być I
instrukcjami, ponieważ mają względne (bezpośrednie) przesunięcie. Również wszystkie instrukcje ładowania i przechowywania są I
formatowane w MIPS. I wreszcie potrzebujemy instrukcji load-top-instant, która będzie I
instrukcją. Nie tylko to, ale R
instrukcje nadal mają 5 dodatkowych nieużywanych bitów (co jest nam potrzebne do natychmiastowego przejścia na natychmiastową zmianę w tej architekturze), więc daje to dodatkową zachętę do przekształcenia natychmiastowych zmian w specjalne (dziwne) R
instrukcje .
Wiele z tych decyzji jest bardziej sztuką niż nauką, ale istnieje logika, którą można dostrzec. Kluczowym celem nie jest, aby liczba instrukcji była tak mała, jak to możliwe, lecz aby uzyskać wysoką wydajnośćdopasowanie potoku na jednym chipie (aby małe firmy, takie jak MIPS i Sun były w latach 80., mogły konkurować z IBM i DEC). (Nazwa RISC, wymyślona przez Davida Pattersona, jest nieco niefortunna. Przykuła uwagę, ponieważ była urocza, a nie dlatego, że „zredukowane instrukcje” są dokładnym opisem tego, co naprawdę próbowały zrobić architektury MIPS i SPARC.) Więc chcesz instrukcje o stałej szerokości (i stosunkowo małej, aby uzyskać lepsze zachowanie pamięci podręcznej I), aby pobieranie, stronicowanie i dekodowanie były prostsze i szybsze. Chcesz części instrukcji, które trzeba wcześniej zdekodować (opcode
, dwa rejestry źródłowe i znak rozszerzony natychmiastowy) mają stałą szerokość i stałą pozycję. Chcesz, aby natychmiastowe elementy były tak długie, jak to możliwe, i chcesz mieć tyle różnych rodzajów instrukcji, ile będą pasować, biorąc pod uwagę wszystkie inne ograniczenia.
Aby zrozumieć formaty instrukcji MIPS I, musisz zrozumieć potok MIPS, a także wrócić do technologii implementacji procesora około 1985 roku. Jeśli spojrzysz na diagram (znasz ten), zobaczysz, że odczyt pliku rejestru znajduje się w Etap identyfikacji, zaraz po IF.
Do celów instrukcji typu R etap identyfikatora musi wykonywać następujące zadania:
Na potrzeby tej dyskusji jest to pierwsze zadanie, o którym musisz pomyśleć. Jeśli jest dużo pracy z dekodowaniem instrukcji, którą musisz wykonać, aby nawet sprawdzić, czy potrzebujesz wartości z rejestrów, zwiększa to opóźnienie przed rozpoczęciem odczytu rejestrów. Zwiększa także złożoność etapu identyfikacji. Rezerwując jeden kod operacji dla wszystkich instrukcji typu R, ograniczasz złożoność do minimum.
Wydaje się trochę dziwne, że poświęcasz pięć bitów tylko przesunięciu. Mogę wymyślić kilka możliwych wyjaśnień. Jednym z nich jest to, że upraszcza routing (te pięć bitów ZAWSZE jest podawanych bezpośrednio do pliku rejestru, te pięć bitów ZAWSZE jest podawanych do manetki beczki, te sześć bitów ZAWSZE jest kierowane do ALU w celu ustalenia, która funkcja ma zostać wykonana).
Być może zastanawiali się nad wprowadzeniem w przyszłości połączonych instrukcji shift-left-and-add. Przypuszczalnie miałoby to postać:
Dzisiaj prawdopodobnie nie zastanawialibyśmy się dwa razy nad bardziej złożonym etapem dekodowania, zwłaszcza, że dostęp do plików rejestrów zdarza się później w potoku typowego superskalarnego procesora. Wiele współczesnych procesorów wykonuje nawet zgrubne dekodowanie instrukcji w momencie wstawienia instrukcji do pamięci podręcznej L1 . Robisz, że linie pamięci podręcznej I są kilka bitów szersze, aby przechowywać dodatkowe informacje (dzięki prawu Moore'a masz wiele tranzystorów do stracenia), aby uprościć i przyspieszyć „właściwe” dekodowanie instrukcji.
Jednym z powodów, dla których prawdopodobnie chcieli utrzymać pole opcode tak małe, jak to możliwe, jest to, aby nie karało to nadmiernie instrukcji typu J. Jak zapewne wiesz, instrukcje typu J używają adresowania pseudo-bezpośredniego. Dla dobra każdego, kto gra w domu, krótko to wyjaśnię.
Pole adresowe instrukcji typu J ma 26 bitów. Ponieważ instrukcje są zawsze wyrównane do 4 bajtów, nie trzeba przechowywać najmniej znaczących dwóch bitów, co oznacza, że efektywnie masz 28 bitów adresu. Jednak przestrzeń adresowa w MIPS I jest 32-bitowa. Zatem cztery górne bity lokalizacji skoku są pobierane z licznika programu.
Oznacza to, że nie można bezpośrednio przeskoczyć do lokalizacji, w której najważniejsze są cztery bity lokalizacji komputera. Zamiast tego musiałbyś wykonać droższy trzyczęściowy skok przez rejestr scratch:
Dzisiaj nie jest tak źle, ale w 1985 r. Jest dużo cykli zegara.
Kradzież trochę z pola adresu jeszcze bardziej zmniejszyłaby efektywny zasięg skoku bezpośredniego. Możesz zobaczyć, że może to być zbyt wysoka cena do zapłacenia.
źródło