Akademia Techniczno-Humanistyczna w Bielsku-Białej
Anatoliy Melnyk
Ćwiczenia laboratoryjne
z przedmiotu „Architektura komputerów”
Bielsko-Biała-2014
Spis treści
Wstęp
Symulator Win DLX.
2.1. Zapuszczenie oraz konfigurowanie.
2.2. Ladowanie programu testowego.
2.3. Symulowanie.
Okno potokowe (Pipeline window).
Okno kodowe (Сode window).
Okno cyklowe (Сlock Cycle window).
Okno punktów zahamowania (przerwy) (Breakpoint window).
Okno rejestrowe (Register window).
Okno statystyki. (Statistics window).
3. Podalsze badania symulatora.
3.1. Zadanie.
3.2. Ułożenie programu.
4. Wstępna praca laboratoryjna
4.1. Zadanie
4.2. Ułożenie programu
4.3. Symulowanie programu bazowego
4.4. Rozdział eksperymentalny
4.5. Wnioski
5. Prace laboratoryjne
5.1. Praca laboratoryjna 1. Program Cycle
5.2. Praca laboratoryjna 2. Program Floating point.
5.3. Praca laboratoryjna 3. Program Factorial
5.4. Praca laboratoryjna 4. Program Simple digit
Appendix: DLX instruction set
1. Wstęp
Procesor DLX (wymawiać jako „Deluxe”) jest procesorem potokowym. Symulator tego procesora o nazwie WinDLX został wynalezieony na Uniwersytecie Wiedeńskim i obecnie jest wykorzystywany jako poglądowa pomoc naukowa do podręczników amerykańskich - założycieli architektury RISC: Patterson D., Hennessy J. Computer Architecture. A quantitative Approach. Second Edition. - Morgan Kaufmann Publishers, Inc., San Francisco, California, 1996. - 760 p.
Przedstawiona informacja na temat symulatora umożliwia opanowanie ułożenia krótkich programów DLX i metodyki wykorzystania symulatora. Zauważmy, że symulator nadaje pomoc kontekstowo-zależną w niedogodnych przypadkach, która jest aktywowywana naciskaniem klawiszu F1.
Symulator Win DLX.
Praca wykonuje się w pliku asemblerowym FACT.S, który zawiera program w języku „Win DLX assembler”. Program oblicza wartości silni liczby całej, wprowadzonej przez operatora z klawiatury. Razem z tym plikiem używa się plik INPUT.S.
2.1. Zapuszczenie oraz konfigurowanie.
WinDLX startuje jako zwykły program Windows. Przy tym otwiera się główne okno z sześcioma obrazkami, które mają status zmniejszonych okienek. Podwójny przytyczek klawiszem myszy otwiera obrazek w zwykłe okno.
Symulator powienien być powrócony do stanu początkowego (rzucony) przy pomocy przytyczka klawiszu myszy, kiedy kursor oznacza opcję Reset all w punkcie File meniu okienka głównego. Przy tym pojawia się okienko modalne „Reset DLX window”, które wymaga podtwierdzenia punktu (komendy) OK do zamknięcia.
WinDLX może działać w kilku konfiguracjach. Na początku pracy z symulatorem należy przekonać się w jego znormalizowanej konfiguracji lub jej odnowieniu. W tym celu wyzwany się punkt meniu Configuration/Floating Point Stages i przekonuje się w ustaleniu następnych jest kodów konfiguracji sprzętu hardwowego (czasem niezbędnie wyprawić wartości kodów na podane niżej wartości).
|
Count |
Delay: |
Addition Units |
1 |
2 |
Multiplication Units |
1 |
5 |
Division Units |
1 |
19 |
Na zakończenie przy pomocy przytyczki myszą na OK zamyka się otwarte okno modalne. Następnie przy pomocy punktu meniu głównego okna Configuration/Memory Size, określa się pojemność informacji jako 0x8000 oraz wychodzi się z potocznego okna modalnego.
Możliwe również stosowanie trzech innych opcji meniu Configuration mianowicie Symbolic addresses, Absolute Cycle Count oraz Enable Forwarding.
2.2. Ladowanie programu testowego.
Do początku symulacji w WinDLX należy załadować programy symulacyjne. Jest to wykonywane przy pomocy punktu meniu File/Load Code or Data. Wybór tego punktu myszą wywołuje nowe okno, które zawiera pliki z rozszerzeniem .S. Właśnie te pliki są załadowane do symulatora. Program p.t. fakt.s oblicza wartość silni liczby całej. Program wspomagający input.s zawiera procedurę zczytywania standartowego wejścia (the keyboard) oraz zachowuje otrzymaną liczbę całą w rejestrze przyznaczenia ogólnego (the general purpose register) r1 DLX procesora. Dla załadowania tych dwóch plików do pamięci symulatora należy:
oznaczyć myszą plik fact.s
nacisnąć myszą przycisk select
oznaczyć myszą plik input.s
nacisnąć myszą przycisk select
nacisnąć myszą przycisk load.
Kolejność nacisków znaków ekranu jest ważna przy określeniu korektnego ciągu ładowania plików-programów do pamięci symulatora. Opracowanie doniesienia File(s) loaded successfully. Reset DLX? wykonywane jest naciskaniem klawiszu OK. Po tej operacji pliki uważane są za ładowane do pamięci symulatora.
Początkowe operacji dobiegły końca. Symulator jest gotowy do wykonania programu.
2.3. Symulowanie.
Teraz w głównym oknu symulatora widać 6 obrazków. Odpowiadającym następnym roboczym i wspomagającym okienkem"Register", "Code", "Pipeline", "Clock Cycle Diagram", "Statistics" and "Breakpoints". Przytyczkiem myszą na każdym obrazku przetwarza jego na otwrzone okienko. Rozpatrzmy przyznaczenie i funkcję tych okienek.
Okno potokowe (Pipeline window).
Najpierw zilustrujemy wewnętrzną strukturę potokowego procesora DLX. Dokonamy przytyczkiem przez klawisz myszy na obrazku Pipeline. Pojawia się „child”- okno, które prezentuje klasyczny 5-jarusowy potokowy DLX - IF, ID, EX, MEM, WB. Otrzymane okno lepiej zrobić bardziej szerokim w celu oglądania szeregu opracowania potokjem standartowych oraz njestandartowych (po wydatkach czasowych) instrukcij komputerowych.
Przedstawiony rysunek odtwarza strukture DLX procesora oraz dodatkowe węzłe wykonania operacji z ruchomym przecinkiem, miamowicie addition/subtraction, multiplication and division.
Okno kodowe (Сode window).
Następne okno nosi nazwę Сode window. Po wykonaniu podwójnego przytyczku na tym oknie pojawia się trzykolumnowe przedstawienie pamięci symulatora, w której odtwarza się (w granicah jednej linijki) następujące dane:
adres (symbolicznie lub liczbowo);
gaksadecymalny maszynowy kod instrukcji;
samą instrukcję zapisaną mową asemblerową.
$TEXT |
0x20011000 |
addi r1, r0, 0x1000 |
Main+4 |
0x0c00003c |
jal InpUnSigned |
Do rozpoczęcia symulowania należy wezwać Execution meniu z głównego okienka. Pojawia się nowe meniu typu pull down. Następnie wykonuje się przytycznek na podfunkcji Single Cycle. Ułatwić działanie można także równoważnym naciskaniem klawiszu F7,co oznacza jeden krok do wykonania symulacji.
Pierwsze naciskanie F7 podświetla w okienku kodowym linie pod adresem $TEXT o żółtym zabarwieniu. Następne naciskanie F7 jest drugim krokiem do symulacji i zmienia podświetlenie pierwszej linii na kolor pomarańczowy, przy tym druga linia otrzymuje żółte podświecenie. W taki sposób zmiany barwy podkreślają proces przesunięcia instrukcji potokem DLX. Skoro okienko Pipeline okazało się zamknięte, jego należy wezwać podwójnym przytyczkiem na odpowiednim oknie. Jeżeli to okno jest niedostatecznie długie i częściowo „ukrywa” odcinek linii, odpowiadającej za graficzne przedstawienie wydatków czasowych na wykowywanie instrukcji, wtedy to okno przedłuża się przy pomocy myszy w kierunku poziomym do uwidocznienia tego, że instrukcja jal InputUnsigned jest ulokowana na schodce IF wtedy, kiedy poprzednia instrukcja addi r1, r0, 0x1000 już przesunięta na drugą schodkę potoku ID. Inne oznaczone krzyżem bloki świadczą o tym, że na odpowiednich schodkach potoku instrukcja nie okazała żadnego działania.
Następne naciskania F7 zmienia barwę okna kodowego,a,więc, dodaje się czerwony kolor, co świadczy o działaniu trzeciej schodki konwejera pod nazwą intEX. Jeszcze jedno naciskanie F7 całkowicie zmienia zabarwienie. Żółta linia powstaje niżej i podobno jest jedyną kolorową linią w oknie. Obserwacja okienka informuje o tym, że schodki potoku IF, intEX and MEM są stosowane, lecz ID - nie. Dlaczego?
2.3.3. Okno cyklowe (Сlock Cycle window).
Inne okna nadają informację o działaniu potoku. Od chwili rozpoczęcia one są zmniejszone czyli wyglądają jako obrazki. Rozkład obrazków jest wykonywany przy pomocy przytyczka klawiszu myszy tylko wtedy, kiedy wskaźnik myszy znajduje się w odpowiednim miejscu głównego (rodzicielskiego) okna.
Z rysunku widać, że symulacja znajduje się na 4-tym cyklu. Pierwsza instrukcja (komenda maszyny) jest opracowywana na schodce MEM potoku, druga- na schodce intEX (integer EX, trzecia - jest anulowana, czwarta- na wejściowej schodce IF. Trzecia instrukcja była załadowana do potoku ”niezgodnie z prawem” („siłą bezwładności”) dlatego, że jej poprzedniczką jest instrukcja przejścia bezwarunkowego. Unieważnienie 3-j instrukcji wywołało „bańkę mydlaną” (“bubble”) na potoce zamiast działania użytecznego.
Celowy adres przejcia jal nosi nazwę „InputUnsigned”. Dla określenia konkretnej wartości liczbowej, odpowiadającej symbolicznemu zapisowi adresu, należy wezwać opcję Memory z meniu głównego okna, zatem - opcję Symbols. Widoczna jest zgodność symbolicznego i liczbowego zapisu naszego innego adresu. Otrzymane wartości zgodności można segregować według nazwy lub wartości liczbowej. Symbol „G” po wartości adresu oznacza powszechny adres celowy, symbol „L” `- miejscowy. Adres celowy „InputUnsigned” ulokowano w modułu „input” dlatego jest powszechnym. Należy zawsze zamykać wezwane okno naciskaniem klawiszu OK.
Naciskanie F7 przesuwa pierwszą instrukcję addi na ostatnią schodkę potoku. Stan rzeczy wewnętrzu konwejera można zrozumieć przy pomocy szybkiego podwójnego przytyczka myszą na linii okna kodowego, czyli w miejscu ulokowania instrukcji addi. Wywołuje to powstanie nowego okna, które zawiera informację szczegółową o mikrowydarzeniach na każdej schodce. Konwejera w danej instrukcji. Nowe okno oznaczono jako „Information about ...". Zamknij nowe okno przy pomocy myszy i przycisku OK. Szybki podwójny przytyczek na linii z instrukcji movi2fp nadaje informację tylko o pierwszej schodce wykonania tej instrukcji z tego powodu, że ona była anulowana przez swojego następcę czyli instrukcją jump. Zamknij to okienko przy pomocy myszy i znaku OK.
Okno informacyjne wyzywa się podwójnym naciskaniem na klawiszu myszy, kiedy wskaźnik myszy jest ulokowany albo na linii maszynowej instrukcji w oknu kodu, albo na pewnej shodce okna konwejerowego.
Okno punktów zahamowania (przerwy) (Breakpoint window).
Wykonując krok za krokiem kod programu naciskaniem klawiszu F7 ,obserwuje się kolejność wyboru instrukcji (komend) w kodowym (programowym) oknie. Następnie przy pomocy okna kodowego widać, że powinne być spełnione dwie identyczne instrukcji ładowania (SW- Store Word), które ładują 32-bitowe słowa do rejestru. Natomiast liczba przytycznek przy pracy wieloskokowej jest zanadto duża i poddaje się zmniejszeniu poprzez użycie punktów przerwy.
Oznaczmy linie 0x0000015c z okna kodowego, które zawiera instrukcję trap 0x5. Jest to systemowe wywoływanie zapisu na ekranie. Przesuń wskaźnik myszy na linie w okienku kodowym wedlug wskazanego adresu i dokonaj przytyczku klawiszem myszy (kolor linii będzie inwertowany). Zatem dokonamy przytyczek na napisie Code w meniu okienka głównego. Wybierz opcję Set Breakpoint przy pomocy jednorazowego przytyczka. Upewnimy się,że niezbędna instrukcja w okienku kodowym jest oznaczona inwertowaniem koloru. Powinno pojawić się nowe okno „Set Breakpoint” co pozwala dokonać wskazania poządanego jarusa potoku, w którym zatrzymuje się wykonanie oznaczonej w okienku kodowym instrukcji. Najczęściej jest wybierana schodka ID. Dla zatrzymania procesu ustalenia punktu zahamowynia wykonuje się przytycznek na znaku OK. Okienko zamknie się.
Zauważmy, że w oknu kodowym na oznaczonej linii inwertowanie koloru zanikło, natomiast pojawią się znak - wskaznik punktu zahamowania „BID” w pobliżu instrukcji wezwania systemowego trap 0x5, która żwiadczy o tym, żr automatyczne wykonanie programu jest zahamowywane w oznaczonej instrukcji na schodce ( inaczej faza lub cykl) dekodowania.
Dla sprawdzenia dostrajania punktu zahamowania należy odmykać okno Breakpoints, które zawiera opisanie naszego punktu w postaci linijki informacyjnej. Punkt można skasować następująco: wykonać przytyczek myszą na linijce opisania punktu, wtedy w mieniu głównego okna powinna pojawi się opcja Breakpoints (przy oznaczeniu linii z opisaniem punktu przerwy). Teraz breakpoint moge byt likwidowane.
Najszybszym sposobem przedlużenia wykonania naszego programu w warunkach automatyctnych jest naciskanie klawiszu F5, zwykłym sposobem - wywołanie myszą punktu meniu okna głównego Execution/Run lub w skrócie F5. Wkrótce pojawi się okno, informujące o wykonaniu zahamowania wyznaczonym punkcie - "ID-Stage: reached at Breakpoint #1"; to okno należy zamknąć podtwierdzeniem myszą jego klawiszu OK.
Zwróćmy się do okienka Clock Cycle Diagram i zauważmy pewną osobliwość. Symulacja powstrzymuje się na cyklu 14, a linia trap 0x5 wygląda jako
T-small oznacza więznienie z powodu wykonania instrukcji trap (pułapka). Z wykresu widać, że głównym motywem jest rzucenie konwejera DLX przy warunku wykonania trap-instrukcji. Jest to najlepszym sposobem przełączenia na inny ,bardziej użyteczny program systemowy. Razem z tym ten sposób upraszcza działania i sterowanie konwejera.Wydarzenie rzucenia (opóźnienia) konwejera jest zafiksowany w okienku informacyjnym, które wykonuje się podwójnym przytyczkiem w warunkach ulokowania wskaźnika myszki na linijce z instrukcją oznaczoną jako punkt przerwy w okienku kodowym - “3 stall(s) because of Trap-Pipeline-Clearing!" in the IF stage”. Zatem należy zamknąć to okno przy pomocy przytyczka na OK.
Instrukcja trap 0x5 pisze informację na ekranie. To można sprawdzić, wykonując przytyczek na opcji Execute/Display DLX-I/O w meniu głównego okna; należy podtwierdzić OK w otwartym oknie.
2.3.5. Okno rejestrowe (Register window).
Podalsze skuteczne wykorzystywanie symulatora zalepy od okna rejestrowego, które otwiera się przy pomocy odpowiedniego przytyczka myszą. Najpierw w oknu kodowym przejdziemy do linii pod adresem 0x00000194. W tym miejscu znajduje się instrukcja
lw r2, SaveR2(r0)
ładowanie słowa i komórki pamięci pod adresem bazowym SaveR2 oraz przesunięciem znajdującym się w rejestrze r0
[ address = base + offset = SaveR2 + (r0) ],
do rejestru r2.
Oznaczmy linie o tej instrukcji jako punkt przerwy. Zrobimy przytyczek myszą na tej linii i naciniemy klawisz Ins (skrócona wersja podania już wiadomego wezwania szeregu Code/Set BreakpointOK). Jeszcze jeden punkt przerwy należy postawić na linii0x000001a4 jar r31. Naciskaniem F5 dokonuje się przedłużenie wykonania programu w warunkach automatycznych. W tym miejscu na użytkownika czeka niespodzianka. Pojawia się okienko wspowadzenie/wyprowadzenie pod nazwą “The DLX-Standard-I/O window”. W tym okienku wskaćik migotuje po doniesieniu "An integer value >1:". Należy nabrać 20 i nacisnąć Enter. Symulacyjne wyzwanie naszego programu trwa do tej pory, dopóki nie będzie osiągnięty punkt zahamowania breakpoint # 2 (OK!).
Schemat (układ) w okienku „the clock cycle diagram window” (otwórz niezbędne okienko) zawiera nowy obszar, mianowicie czerwone i zielone strzałki między instrukcjami (jeżeli tego nie widać, przekręć informację w okienku do powstania symulacyjnych cykłów z liczbami 52, 53, 54, 55, 56). Strzałki czerwone oznaczają niezbędność powstrzymywania potoku (stall); jego przyczynę wskazuje linia, na którą wskazuje strzałka. W naszym przypadku mamy do czanienia z t.zw R-Stalls, czyli z takim, który wynika kosztem RAW-niebezpieczeństwa (Read After Write), czyli jest niekorektnnym wykonaniem tego, że następna instrukcja nie ma prawa zczytywania wartości operanda za rejestru celowego do chwili sformowania wartości operanda poprzednią instrukcją. Zielona strzełka symbolizuje użycie niezbędnego drugiej insrukcji wyprzedzającego przesyłania operanda jeszcze do chwili formalnego zakończenia wykonania poprzedniej insztukcji z opisaniem wyniku do rejestru celowego.
Sprawdźmy zawartość rejestrów. Odtwóżmy okno Register, które może być skrócone do rozmiarów obrazku. W tym okienku są wartości przechowywane w rejestrach. Zwróćmy uwagę na rejestry R1-R5. Wykonując jeszcze jeden krok symulacji do następnego punktu przerwy (F5,OK) widzimy, że niektóre wartości w rejestrze są zmienione wskutek obecności instrukcji lw, załadowanej wartości z pamięci do rejestrów.
Innym sposobem wykonania symulacji bez punktów przerwy w meniu głównego okna realizuje się szeregiem działań Execute/Multiple Cycles lub od razu naciskać F8. Otwarzy się okienko, w którym należy nabrać 17+Enter. Wtedy symulacja będzie trwała 17 cyklów do zahamowania (w opisywanym przypadku nie całkowicie wykonuje się program obliczenia silni).
Zróbmy skroling w okienku the clock cycle diagram dopóki nie pojawią się cykle 72-78. Dwie operacje z ruchomym przycinkiem (multd and subd - multiply/subtract double) są wykonywane na osobnych węzłach na schodce EX potoku. Obie one wymagają na opacowanie operandów kilku taktów. Dlatego następna po nich instrukcja (j Fact.Loop) może być wybrierana, dekodowana oraz wykonana i tylko zatem zahamowana na 1 cykl w celu pozwolenia instrukcji subd skończyć własną fazę MEM.
2.3.6. Okno statystyki (Statistics window).
Jest ostatnim oknem obliczenia statystyk programów symulowanych. Pozwolimy programowi skończyć wykonanie przez naciskanie klawiszem F5. Zobaczymy wiadomość "Trap #0 occurred" (OK), co świadczy o zakończeniu wykonania programu z ostatnią instrukcją trap 0, wykonaną w warunkach symulacji. Pułapka (Trap) pod numerem 0 nie jest określona i stosuje się do zakończenia wykonania pewnego programu. Zamkniemy wszystkie okna i wezwiemy Statistics.
W oknu znajduje się infornacja, zawierająca wszystkie aspekty naszego programu. Wskazano liczbę wykonanych cyklów symalucyjnych, konfigurację budowy, zahamowanie (stalls) razem z przytczkami jego powstania, ciężar właściwy umownego przejści, instrukcję ładowania i przechowywania, instrukcję zawierające operację ruchomego przecinka oraz instrukcji-pułapki (traps). Wszystkie charakterystyki podano w %, na przykład, “RAW stalls: 17(7.91 % of all Cycles)".
Charakterystyki statystyctne są bardzo pożyteczne w badaniach wpływu zmiany konfiguracji budowy na skuteczność (wydajność) maszyny RISC.
Rozpatrzmy, na przykład, wpływ wyprzedzającego przesyłania wyniku od poprzedniej instrukcji-producenta do naszej instrukcji-użytkownika tego wyniku. Innymi słowy, otrzymuje się odpowiedź na pytanie: jak zmienia czas wykonania programu z wyprzedzeniem i bez niego.
W tym celu zanotujemy ogólną liczbę cyklów (215) oraz zahamowań (stalls) - 17 RAW, 25 Control, 12 Trap; 54 Total. Zamknijmy okno statystyki oraz odtwóżmy okno Configuration. Zabronimy wyprzedzenie (disable forwarding) przy pomocy przytyzka na opcji Enable Forwarding (widoczny „hak” lub „ „ ma zniknąć). Następną wiadomość-pytanie symulatora "WARNING: OK resets automatically the processor! Disable Forwarding?" należy odpowiedzieć OK. Zniszczymy wszystkie punkty przerwy przy pomocy meniu Breakpoints, gdzie zadamy opcja Delete All i zakończymy zniszezcnie klawiszem OK. Zatem wezwiemy jednorazową symulację całego programu kolejnie F5, 20 Enter i zatem OK; kiedy wykonuje się trap 0. Drugi przegląd okna statystyki zawiadomi o tym, że liczba zahamowań potoku typu Control stalls oraz Trap stalls pozostaje się bez zmian, lecz liczba RAW stalls wzrosła od 17 do 53 (źle!) powodując wzrost ogólnej liczby cyklów symulacyjnych naszego programu do 236 (było 215). Tak, więc, wyłączenie wyprzedzenia zwiększyło czas wykonania programu o 236/215 = 1.098 i wersja DLXszybsz o 9,8% jest szybsza od DLXneszynsz w programie fact.s.
Podalsze badania symulatora.
Przy pomocy symulatora jest wykonywany szereg rozmaitych badań,mianowicie: zmiana konfiguracji i budowy maszyny w celu uwidoczenienia skutecznego wykorzystania dodatkowego sumatora ruchomego przecinka lub zmianę ogólnej wydajności maszyny kosztem użycia przyśpieszonego węzła (obwodu) dzielenia (z mniejszą liczbą cyklów). Dokonuje się również badania w kwestii wykorzystania optymizującego kompilatora przy pomocy sensownej zmiany kolejności ulokowania instrukcji programu w celu zmniejszebia liczby gróźb typu RAW-stalls.
Należy skutecznie stosować konteksowo-zależną pomóc Help, która zawiera wiele dodatkowej i detalicznej informacji stosującej się dzialania i możliwości symulatora.
Wstępna praca laboratoryjna
4.1. Zadanie.
Ułożyć program asemblerowy dodawania dwóch liczb całych. Zbadać wykonanie tego programu symulatorem DLX. Wyjaśnić oraz przeanalizować informację, otrzymaną w rezultacie wykonania oblilczeń tego programu. Ułożyć sprawozdanie z następną obroną.
4.2. Ułożenie programu.
Niech dwa składnika A i B ulokowano w pamięci głównej pod następnymi adresami oraz nabywają następujących wartości:
Składnik |
Adres |
Wartośc |
А |
0х10 |
0хАА |
В |
0х14 |
0хВВ |
Suma dorównuje 0хАА + 0хВВ = 0х165. Suma powinna zamienić operand 0x14. Tekst programu asemblerowego podamy jako:
; Assumtions:
; R1 initially holds the value 0
; A is an integer, stored beginning at address 0x10
; B is an integer array, stored beginning at address 0x14
;
lw r2,0x10(r1) ;get A value
lw r3,0x14(r1) ;get B value
add r2,r2,r3 ;update A=A+B
sw 0x14(r1),r2 ;store new A
trap 0 ;end
Instrukcją trap #0 należy zakończyć wszystkie programy w przypadku braku dodatkowych środków programowych monitoringu oraz sterowania systemowego.
Program jest plikiem tekstowym typu (my.s), którego tekst wygodnie nabierać środkami menadżera plików FAR.
4.3. Symulowanie programu bazowego.
Kolejnymi rysunkami podano zafiksowany stan symulatora w chwili zakończenia wykonania schodki IF instrukcji nop, nie zależącej już do programu i ulokowaną po instrukcji trap 0. Innymi słowy, wykonanie programu było zatrzymano przez wykonanie instrukcji trap 0, która nadesłała modalną wiadomość “Trap #0 occurred!” pogaszoną przytyczkiem myszy. Następny rysunek zawiera protokół działania konwejera maszyny.
Rys.4.1. Protokół działania potoku.
Opracowano 5 pełnych instrukcji. Na pierwsze cztery instrukcji wytracono 9 cyklów zamiast ośmiu teoretycznie oczekiwanych.Przy tym na wykonanie 3-j i 4-j instrukcji wytracono po 6 cyklów na każdą zamiast pięciu oczekiwanych. Tłumaczy się to zatrzymaniem potoku (R-stall, który dodano w instrukcji 3) przez RAW-zależność danych między instrukcjami 2 i 3; które są wywołane tym zahamowaniem (stall dodany w istrukcji 4) na odpowiedni jeden cykl instrukcji 4. Dobrze widoczne jest wyprzedzające przesyłanie danych do wykonującej schodki instrukcji dodawania, oznaczonej strałkami. W tym miejscu dane nadesłano nie z plika rejestrowego, tylko z odpowiednich pól rejestrowych.
Rys.4.2. Protokół zawartości komóreh głównej pamięci.
Rys.4.3. Protokół statystyczny.
Otrzymaną sumę dorównującą 0хАА + 0хВВ = 0х165 zawiera komórka pod adresem 0x14, o podtwierdza protokół zmiany zawartości komóreh głównej pamięci (rys.4.2). Drugi składnik zamieniono sumą.
Rys.4.3 zawiera ptotokół statystyk otrzymanych pod czas opracowania programu. Charakterystyki tego protokołu określa się przy uwzględnieniu 10 wytraconych cyklów. Zatem podano analizę-objaśnienie każdego rozdziału protokołu statystyk o ręcznym obliczeniu-podtwierdzrniu przedzawionych w protokołe maszynowym wartości charekterystyk statystycznych.
4.4. Rozdział eksperymentalny.
Skorygujemy asemblerowy kod naszego programu według reguł planowania statystycznego, które w sposób rzeczywisty wykonuje automatycznie optymizujący kompilator wprowadzeniem instrukcji nop do zniszczenia zależności danych. Otrzymujemy następujący tekst programu
; Compiler Scheduling. Example DLX code
;
; Assumtions:
; R1 initially holds the value 0
; A is an integer, stored beginning at address 0x10
; B is an integer array, stored beginning at address 0x14
;
lw r2,0x10(r1) ;get A value
lw r3,0x14(r1) ;get B value
nop ;compiler scheduling, cycle bypass
add r2,r2,r3 ;update A=A+B
sw 0x14(r1),r2 ;store new A
trap 0 ;end
Protokół działania konwejera podano na rys.4.4.
Rys.4.4. Protokół działania dla programu eksperymentu z planowaniem statycznym.
Widać, że zahamowania zanikły. Następnie rozglądamy inne protokoły, jak to było dokonano wczęśniej.
Nasze propozycję co do usunięcia zależności danych w sposób statycznego dyspozytorowania są podtwierdzone.
4.5. Wnioski
Istnienie właściwych zależności danych programu wywołało powstanie zależności RAW, która została określona automatycznie i zniszczyła poprzez zahamowanie o 1 cykl zniszczył sprzęt maszyny. Przy tym strata szybkości działania wynosi 1-9/8=-12,5%.
Mośliwe jest zniszczenie zależności danych przez wprowadzenie instrukcji nop po drugiej instrukcji programu, co odpowiada nie dynamicznemu,a statycznemu planowaniu procesu wykonania programu.
W dużych programach są spotykane przypadki, w których przy stytycznym planowaniu kompilator zamiast operacji nop wprowadza pożyteczną ulokowana bliżej do początku programu instrukcję oraz wtedy, kiedy jego przesunięcie (po kolejnym opracowaniu) nie zniekształca programu.
Prace laboratoryjne
Praca laboratoryjna zawiera dwie części: bazową oraz eksperymentalną. Celem wykonania części bazowej każdej pracy laboratoryjnej jest opanowanie przez studenta technologii obróbki strumienia instrukcji konwejerem procesora uniwersalnego (na przykładzie obróbki pewnego typu programów) oraz otrzymanie nawyków ilościowej oceny skutechności mikroarchitektury procesora.
Celem wykonania części eksperymentalnej odpowiedniej pracy laboratoryjnej jest otrzymanie nawyków w samodzielnym planowaniu eksperymentu oraz rozwiązania wynikających zadań inżenieryjnych z podalsza oceną skutechności proponowanych i realizowanych przez nich propozycji według wybranych przez studenta kryteriów.
Prace laboratoryjne rozróżnia się zgodnie z typem programu symulowanego. Przy tym części bazowa (B) i eksperymentalna (E) mają formalnie zbieżne zadania, jak to będzie podano niżej.
Zadanie do pracy 1B.
1.Załadować bazysową wersję programu do symulatora. Zaplanować wykorzystanie komórek głównej pamięci oraz zapisać do nich dane wyjściowe.
2. Wykonać program w reżymie skokowym. Sprawdzić rezultaty wykonania programu.
3. Wyjaśnić podane przez okna (okno cyklowe, okno stytystyczne) symulatora protokoły wykonania programu.
4. Wyciągnąć wnioski zgodnie wyników symulacji wykonania programu.
5.Opracować sprawozdanie B z następną obróbką.
Zadanie do pracy 1E.
1.Zaproponować metody skuteczności wykorzystania śródków aparatowych procesora i opracować odpowiednią eksperymentalną wersję programu bazowego .
2. Wykonać program eksperymentalny w reżymie skokowym. Sprawdzić wynik wykonania programu.
3. Wyjaśnić podane w okienkach (okno cyklowe, okno statystyk) symulatora protokoły wykonania programu.
4. Przedstawić ilościowe wartości charakterystyk udowadniających wzrost skuteczności działania sprzętu.
5.Wyciągnąć wnioski zgodnie z wynikami wykonania eksperymentu.
6.Opracować sprawozdanie E z następną obroną.
Sprawozdanie zawiera:
-stronę tytułową;
-zadanie (bazowe lub eksperymentalne,w tym tekst programu);
-cel pracy;
-planowanie wykorzystania komórek pamięci głównej (w pracy B);
-istotę eksperymentu;
-niezbędne wyjątki z protokołów wytworzonych symulatorem zgodnie z wynikami opracowania programu);
-ścisłe wyjaśnienie wyników, zawierających wyjątki;
-wartości liczbowe charakterystyck ilościowych udowadniających skutechność lub tych, które obalają skutechność zaproponowanej przez studenta eksperymentalnej wersji programu w porównaniu z programem bazowym (tylko w pracy E);
-ścisłe wnioski.
Zakres pracy- 10 stron.
Praca laboratoryjna 1. Program Cycle
Bazowa wersja programu.
;****************************************************************
;* Example DLX code without the use of loop unrolling and *
;* rescheduling. *
;* Assumtions: *
;* R1 initially holds the value 0 *
;* A is an integer array, stored beginning at address 0 *
;* B is an integer array, stored beginning at address 4000 *
;* *
;* Written by Dr. Michelle Hugue *
;* (Worksheet Loop Unrolling and Rescheduling 1) *
;****************************************************************
Loop:
lw r2,0(r1) ;get next A value
lw r3,20(r1) ;get next B value
add r2,r2,r3 ;update A
sw 40(r1),r2 ;store new A
addi r1,r1,#4 ;update counter
subi r4,r1,#16 ;check to see if done
bnez r4,Loop ;repeat loop if not done
trap 0 ;end
Praca laboratoryjna 2. Program Floating point.
Bazowa wersja programu.
;*********************************************************
;*This example calculates the equation: (A*B)+(C*D) *
;*We are assuming that the value of A is stored at *
;*location 100; B is at 200; C, 300; D, 400. The result *
;*will be stored at location 500. *
;*A, B, C, and D are all 32 bit integers *
;*********************************************************
Equation:
lw r1,100(r0) ;load A
lw r2,200(r0) ;load B
lw r3,300(r0) ;load C
lw r4,400(r0) ;load D
movi2fp f1,r1 ;convert A into floating pt
movi2fp f2,r2 ;convert B to fp
movi2fp f3,r3 ;convert C to fp
movi2fp f4,r4 ;convert D to fp
multf f5,f1,f2 ;A*B is stored into f1
movfp2I r1,f5 ;move f1 to r1
multf f6,f3,f4 ;C*D is stored into f3
movfp2I r3,f6 ;move f3 to r3
add r1,r1,r3 ;(A*B)+(C*D)
sw 500(r0), r1 ;store result at mem[500]
trap 0 ;end
Praca laboratoryjna 3. Program Factorial
Bazowa wersja programu.
; WINDLX Ex.3: Factorial
; (c) 1991 Guenther Raidl
; Modified: 1992 Maziar Khosravipour
; Program begin at symbol main
; requires module INPUT
; read a number from stdin and calculate the factorial (type: double)
; the result is written to stdout
;---
.data
Prompt: .asciiz "An integer value >1 : "
PrintfFormat: .asciiz "Factorial = %g\n\n"
.align 2
PrintfPar: .word PrintfFormat
PrintfValue:.space 8
.text
.global main
main:
;--- Read value from stdin into R1
addi r1,r0,Prompt
jal InputUnsigned
;--- init values
movi2fp f10,r1 ;R1 -> D0 D0..Count register
cvti2d f0,f10
addi r2,r0,1 ;1 -> D2 D2..result
movi2fp f11,r2
cvti2d f2,f11
movd f4,f2 ;1-> D4 D4..Constant 1
;--- Break loop if D0 = 1
Loop: led f0,f4 ;D0<=1 ?
bfpt Finish
;--- Multiplication and next loop
multd f2,f2,f0
subd f0,f0,f4
j Loop
Finish: ;--- write result to stdout
sd PrintfValue,f2
addi r14,r0,PrintfPar
trap 5
;--- end
trap 0
Praca laboratoryjna 4. Program Simple digit
Bazowa wersja programu.
; WINDLX Exp.2: Generate prime number table
; (c) 1991 Guenther Raidl
; Modified 1992 Maziar Khosravipour
; Program begins at symbol main
; generates a table with the first 'Count' prime numbers from 'Table'
;---
.data
;--- size of table
.global Count
Count: .word 10
.global Table
Table: .space Count*4
.text
.global main
main:
;--- Initialization
addi r1,r0,0 ;Index in Table
addi r2,r0,2 ;Current value
;--- Determine, if R2 can be divided by a value in table
NextValue: addi r3,r0,0 ;Helpindex in Table
Loop: seq r4,r1,r3 ;End of Table?
bnez r4,IsPrim ;R2 is a prime number
lw r5,Table(R3)
divu r6,r2,r5
multu r7,r6,r5
subu r8,r2,r7
beqz r8,IsNoPrim
addi r3,r3,4
j Loop
IsPrim: ;--- Write value into Table and increment index
sw Table(r1),r2
addi r1,r1,4
;--- 'Count' reached?
lw r9,Count
srli r10,r1,2
sge r11,r10,r9
bnez r11,Finish
IsNoPrim: ;--- Check next value
addi r2,r2,1 ;increment R2
j NextValue
Finish: ;--- end
trap 0
Appendix: DLX instruction set.
Instruction type/opcode |
Instruction meaning
|
Data transfers |
Move data between registers and memory, or between the integer and FP or special registers; only memory address mode is 16-bit displacement + contents
|
LB, LBU, SB |
Load byte, load byte unsigned, store byte |
LH, LHU, SH |
Load halfword, load halfword unsigned, store halfword
|
LW, SW |
Load word, store word
|
LF, LD, SF, SD |
Load single precision float, load double precision float, store single precision float, store double precision float
|
MOVI2S, MOVS2I |
Move from/to integer register to/from a special register
|
MOVF, MOVD |
Copy one floating point register or a DP pair to another register or pair |
MOVFP2I, MOVI2FP |
Move 32 bits from/to a FP register to/from an integer register |
Arithmetic, logical |
Operations on integer or logical data in integer registers; signed arithmetic instructions trap on overflow |
ADD, ADDI, ADDU, ADDUI |
Add, add immediate (all immediates are 16 bits); signed and unsigned |
SUB, SUBI, SUBU, SUBUI |
Subtract, subtract immediate; signed and unsigned |
MULT, MULTU, DIV, DIVU |
Multiply and divide, signed and unsigned; operands must be floating-point registers; all operations take and yield 32-bit values |
AND, ANDI |
And, and immediate |
OR, ORI, XOR, XORI |
Inclusive or, Inclusive or immediate, exclusive or, exclusive or immediate |
LHI |
Load high immediate - loads upper 16 bits of register with immediate and zeros the lower 16 bits |
SLL, SRL, SRA, SLLI, SRLI, SRAI |
Shifts; both immediate (S__I) and variable form (S__); shifts are left logical, right logical and right arithmetic |
SEQ, SNE, SLT, SGT, SLE, SGE |
Set conditional; set equal zero, set not equal zero, set less than, set greater than, set less than or equal, set greater than or equal |
Control |
Conditional branches and jumps; PC-relative or through register |
BEQZ, BNEZ |
Branch integer register equal/not equal to zero; 16 bit offset from PC+4 |
BFPF, BFPT |
Test comparison bit in the FP status register and branch; 16 bit offset from PC+4 |
J, JR |
Jumps; 26 bit offset from PC+4 (J) or target register (JR) |
JAL, JALR |
Jump and link; save PC+8 to R31, target is 26 bit offset from PC+4 (JAL) or a register (JALR) |
TRAP |
Transfer to operating system at a vectored address |
RFE |
Return to user code from an exception; restore user mode |
Floating point |
Floating-point operations on DP and SP floats |
ADDD, ADDF |
Add DP and SP floats |
SUBD, SUBF |
Subtract DP and SP floats |
MULTD, MULTF |
Multiply DP and SP floats |
DIVD, DIVF |
Divide DP and SP floats |
CVTD2F, CVTD2I, CVTF2D, CVTF2I, CVTI2D, CVTI2F |
Convert instructions; CVTx2y converts from type x to type y, where x and y are one of D (double precision float), F (single precision float) or I (integer); both operands are in floating point registers |
EQD, EQF, NED, NEF, LTD, LTF, GTD, GTF, LED, LEF, GED, GEF |
DP and SP compares; set comparison bit in FP status register |