UNIVERSITETET I OSLO Det matematisk-naturvitenskapelige fakultet Eksamen i IN 47 Program- og maskinvare Eksamensdag: 27. mai 998 Tid for eksamen: 9. 5. Oppgavesettet er på 8 sider. Vedlegg: Tillatte hjelpemidler: Ingen Alle Kontroller at oppgavesettet er komplett før du begynner å besvare spørsmålene. Dette oppgavesettet består av 5 oppgaver som kan løses uavhengig av hverandre. Alle oppgavene er vektet likt. Der det er snakk om programmering, skal programmene lages slik at de kan kompileres eller assembleres med cc på SGI-maskinene her ved Ifi. Hvis du synes punkter i oppgaven er uklart definert, kan du angi hvilke forutsetninger du tar hensyn til i din løsning. Lykke til! Oppgave Oversettelse (total vekt 2%) Disse tre deloppgavene går ut på å oversette mellom C og IPS assemblerkode. Det er ikke nødvendig å ta hensyn til prosessorens pipeline. -a Enkel variant (vekt 6%) Funksjonen iavg i figur beregner gjennomsnittet av n int-verdier. (Vi regner at en int er på 4 byte.) Anta at n. Oversett denne funksjonen til IPS assemblerkode. Hint Det er ikke nødvendig å forstå alle detaljer i funksjonen for å kunne oversette den. -b Variant med funksjon (vekt 7%) Funksjonen fiavg i figur 2 fungerer som iavg i oppgave -a, men hvert vektorelement blir bearbeidet av funksjonen fx før det summeres. Oversett denne funksjonen til IPS assemblerkode. (Fortsettes på side 2.)
Eksamen i IN 47, 27. mai 998 Side 2 int iavg(int a[], int n) { int sum =, i; Figur : En C-funksjon for å beregne gjennomsnitt for (i = ; i < n; ++i) sum += a[i]; } if (sum < ) sum -= n/2; else sum += n/2; return sum/n; Figur 2: En variant av funksjonen i figur int fiavg(int a[], int n, int (*fx)(int)) { int sum =, i; for (i = ; i < n; ++i) sum += fx(a[i]); } if (sum < ) sum -= n/2; else sum += n/2; return sum/n; Hint I denne oppgaven er det spesielt viktig å behandle de sikre («callee save») og usikre («caller save») registrene riktig. -c Oversettelse fra assemblerspråk til C (vekt 7%) I figur 3 er vist koden til en ukjent funksjon f som har følgende signatur i C: float f(float a[], int n) Prøv å forstå hva denne funksjonen gjør, og oversett den til C. Hint Siden parameteren a er en peker (til en vektor), overføres den i register $a. Returverdien skal ligge i register $f. Hint Operasjonen mtc zero,$f flytter et ord fra register zero i CPU-en til register $f i flyttallsprosessoren. (Det står omvendt i læreboken.) Oppgave 2 Kontroll av en datapath (total vekt 2%) Figur 4 viser datapath-en for en enkel IPS prosessor, og ett bit av ALU-en er vist i figur 5. Kontrollordet i figur 6 er basert på formatet i figur 7 og beskriver hvordan datapath-en blir styrt for en ukjent instruksjon. Hensikten med denne oppgaven er å finne ut hva denne instruksjonen gjør. Signalene i kontrollordet svarer til kontrollsignaler til datapath-en (figur 4) og til ALU-en (figur 5). CarryIn brukes som mente inn på minst signifikante bit i ALU-en. Forøvrig inneholder ALU-en logikk for å generere Zero og Less. (Fortsettes på side 3.)
Eksamen i IN 47, 27. mai 998 Side 3 #include <regdef.h>.text.globl f f: mtc zero,$f cvt.s.w $f,$f add t,zero,zero loop: lw t,(a) mtc t,$f4 c.lt.s $f4,$f bct next mov.s $f,$f4 next: addi a,a,4 addi t,t, bne t,a,loop jr ra Figur 3: En ukjent funksjon f 2-a Operasjon (vekt 7%) Hvilken operasjon (ALUresult = A op B) blir ALU-en styrt til å utføre? Hint Hva er toer-komplement av ~x? (Tegnet ~ er C-notasjon for en maskeoperasjon.) 2-b Instruksjonen (vekt 7%) Forklar kort hva instruksjonen gjør og hva den kan brukes til. Hint Hva er formålet med XOR-porten som InvZero går inn på (i figur 4)? 2-c Generalisering av instruksjonen (vekt 6%) I figur 7 er det spesifisert at register skal brukes som det ene argumentet, men man kan tenke seg å legge en referanse til et annet register inn i RSfeltet. Hva må man i så fall passe på når man lager den verdien som skal ligge i dette registeret? Oppgave 3 Hukommelseshierarki (total vekt 2%) Figur 8 viser en liten bit med kode som kopierer mellom to områder i hukommelsen. Koden er schedulert for en IPS-prosessor med pipeline og «delayed load» og «delayed branch». Anta at: loop ligger på adresse x4233 t inneholder verdien x3 t inneholder verdien x2c t2 inneholder verdien x34 (Fortsettes på side 4.)
Eksamen i IN 47, 27. mai 998 Side 4 Figur 4: En datapath. shift left 2 ux ux 4 add instruction [3 26] InvZero control RegDst Jump Branch emread emtoreg ALUOp emwrite ALUSrc RegWrite shift left 2 add PC Read address instruction memory instruction [3 ] instruction [25 2] instruction [2 6] instruction [5 ] ux read register read register 2 registers write read register data 2 write data read data u x A ALU zero B ALU result address write data read data data memory ux instruction [5 ] sign extend ALU control Ainvert Binvert CarryIn instruction [5 ] Operation Figur 5: En ALU. Ainvert Binvert Operation CarryIn a Result b + 2 Less 3 CarryOut Figur 6: Kontrollord for en ukjent instruksjon. RegDst ALUSrc emtoreg RegWrite emread emwrite Branch Operation Ainvert Binvert CarryIn Jump InvZero 2 OP Figur 7: Formatet på instruksjonen. RS== RT address/immediate (Fortsettes på side 5.)
Eksamen i IN 47, 27. mai 998 Side 5.set noreorder Figur 8: Kode som kopierer mellom to områder. loop: lw t3,(t) # read from source addi t,t,4 # increment pointer to source sw t3,(t2) # write to destination addi t,t,- # update remaining number of words bne t,zero,loop # repeat until t == addi t2,t2, 4 # increment pointer to destination.set reorder 3-a Adressereferanser (vekt 7%) Under kjøring av programmer må maskinvaren generere adresser for både instruksjoner og data. Skriv ned sekvensen med adresser som blir generert når koden i figur 8 blir utført. 3-b Simulering av en «direct mapped» cache (vekt 7%) Anta en «direct mapped» cache på 6 ord og med 8 byte per cache-linje som i utgangspunktet er tom. Cache-en bruker en «write back»-strategi, og tar alltid vare på det refererte ved «miss» (både lesing og skriving). Videre er cache-en felles for både instruksjoner og data. Simulér bruk av adressereferansene fra oppgave 3-a mot en slik cache. Vis hvordan «hit» og «miss» fordeler seg, og hva det endelige innholdet av cache-en blir. 3-c Omgjøring av tilpassing til pipelining (vekt 6%) Som nevnt er koden i figur 8 schedulert for pipelining. Forklar hvordan dette har vært gjort, og tilbakefør koden til det den kan ha vært før den ble schedulert. Oppgave 4 Delt lager i software (total vekt 2%) an kan flytte programmer fra maskiner med cache-koherens i hardware til et cluster. Et cluster er en parallell maskin som faktisk ikke har felles hukommelse, for eksempel arbeidsstasjoner som er knyttet sammen med et nettverk. I figur 9 er det vist hvordan dette er tenkt gjort ved at koden fra figur 8 er utvidet med makroene cache_load og cache_store før henholdsvis «load»- og «store»-instruksjoner. Disse makroene vedlikeholder den programmerte cache-en i systemet. akroene cache_load og cache_store må sikre at instruksjonen som kommer rett etter kan bruke det som ligger i cache-en. Det betyr at for alle aksesser som ikke kan bruke det som er i den simulerte cache-en («miss» eller feil tilstand), må koden i makroene kommunisere med prosesser på andre maskiner i clusteret for å få tak i de rette dataene, i riktig tilstand. Denne kommunikasjonen skjer ved meldingsutveksling. Figur viser en skisse av hvordan cache_load og cache_store samvirker med andre prosesser via utveksling av meldinger. Dette samvirket er basert (Fortsettes på side 6.)
Eksamen i IN 47, 27. mai 998 Side 6 Figur 9: Kode fra figur 8 med utvidelser som sørger for at den programmerte cache-en har riktig tilstand før «load»- og «store»-instruksjoner..set noreorder loop: cache_load(+t) # check before load lw t3,(t) # read from source addi t,t,4 # increment pointer to source cache_store(+t2) # check before store sw t3,(t2) # write to destination addi t,t,- # update remaining number of words bne t,zero,loop # repeat until t == addi t2,t2, 4 # increment pointer to destination.set reorder Figur : Skisse av samvirket med andre prosesser via meldingsutveksling. void remote_interaction(int type, unsigned address, unsigned char old_state, unsigned char new_state) { /* send request to the responsible node */ } send(type, address, data, old_state, new_state); msg = receive(); while (msg.type!= RESPONSE) /* other message */ { serve requests from other nodes and process msg msg = receive(); } /* response received */ update cacheline and corresponding state på polling, og mens en prosess venter på å få svar på sin utestående forespørsel 2 om en cache-linje i en gitt tilstand, betjener den henvendelser fra andre prosesser som aksesserer data som den selv har lagt i cache-en. Parametrene som opptrer i figur har følgende betydninger: type har verdiene REQUEST eller RESPONSE, og skiller mellom forespørsler og svar address er adressen som den programmerte cache-en sjekker old_state er tilstanden den tilhørende cache-linjen er i new_state er den ønskede tilstanden på cache-linjen data er innholdet i den aktuelle cache-linjen Figur viser hvordan hver prosess i et slikt system setter av plass i sitt virtuelle adresserom til en cache og tilstand for cache-en. Cache-en ligger fra x8, mens tilstanden for cache-linjene ligger fra x2. En gitt type == RESPONSE 2 type == REQUEST (Fortsettes på side 7.)
Eksamen i IN 47, 27. mai 998 Side 7 Figur : Plassering av cache for delte data og den nødvendige tilstand i en prosess virtuelle hukommelse. xffffffff shared data x8 state table x2 x cache-linje får dermed samme virtuelle adresse hos alle deltagende prosesser. Hver cache-linje kan være i én av tre tilstander: Invalid Denne cache-linjen er ikke gyldig for denne prosessen Read Only Denne cache-linjen kan leses, og andre prosesser kan også ha gyldige kopier Read/Write Denne cache-linjen kan leses og skrives, og ingen andre prosesser har gyldige kopier 4-a Å simulere en cache (vekt 7%) Anta cache-linjer på 64 byte, at det er satt av byte for tilstand per cachelinje, og at kode tilsvarende den i figur blir brukt når det er nødvendig å kommunisere med andre prosesser. Skissér i C-kode hvordan makroen cache_store sikrer at det er «cache hit» og at cache-linjen er i tilstanden Read/Write før store-operasjonen faktisk gjennomføres. Husk å antyde hvor koden fra figur skal være. 4-b Avbrudd i stedet for polling (vekt 6%) I et system som bruker denne teknikken er mottak av meldinger basert på polling i stedet for avbrudd («interrupt»). På denne måten blir meldinger fra andre prosessers koherenssystem behandlet mens mottakeren aktivt venter på et utestående svar. Hvordan må man gå fram hvis kommunikasjonen skal være basert på avbrudd i stedet for polling, og hva er ulempene med å bruke avbrudd? (Fortsettes på side 8.)
Eksamen i IN 47, 27. mai 998 Side 8 4-c Prosedyrer eller makroer (vekt 7%) Ovenfor er cache_load og cache_store omtalt som makroer. I stedet kan de bli implementert som prosedyrer. Hva er forskjellen på prosedyrer og makroer, og hva blir konsekvensene for dette systemet om prosedyrer blir brukt i stedet for makroer? Oppgave 5 En lagerprosess (total vekt 2%) Figur 2: To prosesser med felles lager L - Felles lager - Som vist i figur 2 har vi to prosesser L og som kommuniserer via et felles lager med følgende struktur: typedef struct { int code; unsigned char data[2]; } comm_data; Tanken er at L skal fungere som lager for : Hvis setter verdien i code-feltet og en tekst (avsluttet med -byte) i data-feltet, skal L ta vare på en kopi av teksten. Hvis setter verdien i code-feltet, skal L kopiere den siste teksten den tok vare på, over i data-feltet så kan hente den derfra. Det skal benyttes semaforer til å synkronisere dataoverføringen. Det er viktig at prosessene er blokkert når de ikke har noe å gjøre. 5-a Implementasjon med semaforer (vekt %) Skriv koden for prosessen L samt hvilke semaforer som trengs for å styre synkroniseringen. (Det er altså ikke nødvendig å skrive koden for.) Det er ikke nødvendig å skrive kode som skal kunne kompileres; det er nok å deklarere semaforer med datatypen semaphore og bruke operasjonene up og down. Hint tekst. Legg merke til at i denne deloppgaven skal ikke L lagre mer enn én 5-b Utvidet implementasjon (vekt %) Utvid koden for L fra oppgave 5-a slik at L kan lagre de 2 siste tekstene den får fra. Bruk en ringbuffer til å lagre tekstene. Når L får i code-feltet, skal den returnere en kopi av den siste teksten; når den får 2, skal den sende tilbake den nest siste, osv.