Dal busy-wait
all’interrupt
Costo aggiuntivo del busy-wait in un sistema di I/O
2. CDROM player (20X)=> trasferisce dati al processore in blocchi da 8 bytes ad un tasso di 3 MB/s. Non è permesso perdere dati.
3. Hard Disk => trasferisce dati in blocchi da 4 longwords con un
throughput max di 16 MB/s. Di nuovo non è permesso Si assuma che per l’interrogazione di un dispositivo, incluso il
trasferimento del controllo alla procedura di gestione, l’accesso al dispositivo, ed il ritorno al programma utente, siano necessari 400 cicli e che il processore lavori con una frequenza di clock di 2 GHz.
Si calcoli la frazione di tempo di CPU consumata nei seguenti casi, assumendo che si esegua una interrogazione del dispositvo tramite busy-wait con una frequenza sufficiente a far sì che nessun dato venga mai perso e supponendo che i dispositivi siano potenzialmente sempre al lavoro.
1. Mouse => per non perdere alcun movimento dell’utente deve essere interrogato almeno 30 volte al secondo.
Soluzione (1)
Cicli di clock per secondo per l’interrogazione=
30 * 400=12000 cicli/sec
% cicli di clock del processore utilizzati= 12 * 103 = 0,0012%
1000 * 106
Frequenza di interrogazione=3000 Kb/sec =375K accessi/sec 8 byte/accesso
Cicli per secondo spesi dalla CPU= 375K * 400 = 150*106
% processore utilizzato= 150 * 106 = 7,5%
2000 * 106
CD-ROM PLAYER (20x =>3 MB/sec) MOUSE
Ignoriamo la discrepanza tra base 2 e base 10
Soluzione (2)
Frequenza di interrogazione=16 Mb/sec =1 M=10 6 accessi/sec 16 byte/accesso
Cicli per secondo spesi= 400 * 106
% processore utilizzato= 400 * 106 = 20%
2000 * 106 HARD DISK
Ignoriamo la discrepanza tra base 2 e base 10
Osservazione: Per il mouse l’ipotesi di costante attività ha senso e l’
overhead è accettabile (frequenza di interrogazione necessaria è bas-
sa). CD-ROM e HD sono attivati solo quando è esplicitamente richiesto dal sistema operativo, e non costantemente. L’overhead medio è quindi minore a quello da noi calcolato, assumendo che il dispositivo sia
sempre attivo. Tuttavia, nel momento in cui il SO inizia una
operazione sul dispositivo, questo deve essere interrogato costantemente perché non è possibile sapere a priori quando il dispositivo avvierà
Come ridurre tale overhead?
Idea : utilizzare un meccanismo per segnalare al processore quando un dispositivo di I/O richiede la sua attenzione=> le interruzioni.
Problemi:
1. Evitare che il verificarsi di un’interruzione non provochi interferenze indesiderate con il programma interrotto. =>
Salvataggio del contesto
2. Una CPU può colloquiare con diversi devices, i quali devono
essere gestiti tramite routine specifiche => necessità di identificare l’origine dell’interruzione
3. Gestire richieste concorrenti di interruzione o interruzioni che
pervengono al processore mentre è già in corso un’interruzione (si dovrà interrompere la routine di servizio del primo interrupt?).
=>definizione della gerarchia di priorità.
Fasi per la gestione dell'interruzione
a) salvare lo stato del processo in esecuzione;
b) identificare il programma di servizio relativo all'interruzione;
c) eseguire il programma di servizio;
d) riprendere le attività lasciate in sospeso.
Context switch
Il contesto su cui opera un programma è costituito da:
•Il registo PC: contiene l’indirizzo dell’istruzione da cui dovrà essere ripresa l’esecuzione del programma interrotto
•Il registro di stato
•I registri del modulo ALU, compresi i bit di condizione, che possono contenere valori che il programma interrotto non ha terminato di
elaborare. Gestendo l’interruzione solo prima della fase di fetch, quando l’esecuzione dell’istruzione precedente è completamente
conclusa, possiamo evitare di memorizzare sia questi registri, che lo stato del microprogramma.
Quando si verifica un’interruzione avviene una commutazione dal contesto del programma interrotto a quello della routine di servizio.
Analogamente il contesto del programma interrotto deve essere ripristinato una volta conclusa la routine di servizio.
Context switch (2)
Occorre impedire che si verifichino altre interruzioni mentre sono in corso le operazioni di commutazione, pena possibili incongruenze tra i valori presenti nei registri di un contesto commutato solo
parzialmente. Per fare ciò quando, al termine dell’esecuzione di
un’istruzione, il segnale IRQ=0 assume valore 1, il flip-flop I viene settato a 0 via firmware. Inoltre il PD32 prevede a salvare nello stack lo SR e il PC. Infine, nel PC è caricato l’indirizzo della routine di
servizio del device che ha richiesto l’interruzione.
I CPU
INT
IRQi+1 IRQi
IRQi-1
Vcc
Modulo interfaccia i-1
Modulo interfaccia i
Modulo interfaccia i+1
Riconoscimento delle interruzioni (IVN)
Periferica CPU
IACKINT
identificazione periferica
Indirizzo 0
iniziale 1
prog.servizio 2
prima perife.
3
Indirizzo 4
iniziale 5
prog.servizio 6
seconda perife.
7
Indirizzo 4*i
iniziale 4*i+1
...
prog.servizio 4*i+2
perife. i-esima 4*i+3
PUSH …
POP RTI
...
Identificativo Periferica x 4
Meccanismo di interruzione multilivello
(a polling o vettorizzata)
CONTROLLORE INTERRUZIONI a PRIORITA’
QS R QS R
INT0 LIVELLO 0
P01 P02 P0K
IR IR IR
QS R QS R
INT1
IFF1
LIVELLO 1
P11 P12 P1K
IR IR IR
ACK0
ACK1
QS R QS R
INTL LIVELLO L
PL1 PL2 PLK
IR IR IR
ACKL
MFF1IFFLMFFLIFF0MFF0
…
Aumento della priorità
Aumento della priorità
PD 32
IRQ IACK
Alcune Istruzioni per la gestione dell’I/O (Classe 7)
CLEAR dev - - - - Viene azzerato il flip-
flop STATUS del dev e senza avviare
l'operazione.
SETIM dev - - - - Viene abilitato il
device dev ad inviare interruzioni: IM=1
CLRIM dev - - - - Viene disabilitato il
device dev ad inviare interruzioni: IM=0
JIM dev, D1 - - - - Se IM=1 salta alla
destinazione D1
JNIM dev, D1 - - - - Se IM=0 salta alla
Scambio di dati da periferica di input e periferica di output
Si vuole realizzare lo scambio dei dati, in formato byte, da una periferica di input e una di output. Lo scambio avverrà attraverso
l’uso di un buffer, di un byte, allocato in RAM. La periferica di input caricherà il buffer con il dato “prodotto”, quella di output lo
scaricherà “consumandolo”.
Si deve inoltre impedire che la periferica di input possa inviare un nuovo dato, fino a che il buffer non sarà vuoto. Analogamente la periferica di output non potrà consumare dati se il buffer è vuoto.
Interru
pt da IN PUT
device Interrupt da
OUTPUT device
Salva R0 nello stack
Buffer pieno si
Inibisce INPUT dev CLRIM input Ripristina contesto
ed esci Setta flag:
buffer pieno
no
INB input,buffer START input
Output device ha IM abilitato?
si
no
Ripristina contesto
SETIM output
Salva R0 nello stack
Buffer vuoto si
no Inibisce OUTPUT dev
CLRIM output Ripristina contesto
ed esci Resetta flag:
buffer vuoto OUTB buffer,output
START output
INPUT device ha IM abilitato?
si
no
Ripristina contesto
SETIM input
; PROGRAMMA DIMOSTRATIVO SULL'USO DEI DEVICES
; Una periferica di input invia dati in un buffer di 1byte con il meccanismo degli
; interrupt, la periferica di output preleva il dato dal suddetto buffer
; Nel simulatore è necessario installare due periferiche:
; INPUT: I/O=I, ind=30h, IVN=2
; OUTPUT: I/O=O, ind=56h, IVN=7
org 400h ;INIZIO PROGRAMMA input equ 30h ;indirizzo periferica input output equ 56h ;indiririzzo periferica output
flag db 0 ;flag =0 buffer vuoto, flag=1 buffer pieno buffer equ 500h ;indirizzo buffer di scambio
code ;inizio istruzioni
seti ;abilita PD32 ad accettare interruzioni
setim input ;abilita periferica di input ad accettare interruzioni setim output ;abilita periferica di output ad accettare interruzioni start input ; avvio produzione del dato
start output ; avvio consumo del dato
main: jmp main ; progr. Principale = loop infinito
;DRIVER DI INPUT
;Invia dati al buffer se questo e' pieno pone in attesa la periferica
;di input 0->IM, sblocca (se in attesa) la periferica di output 1->IM driver 2, 600h ;Il driver della periferica con IVN=2
;inizia dall'ind. 600h pinput: push r0 ;salva contenuto di R0
movb flag,r0 ;carica flag in R0
cmpb #1,r0 ;controlla se buffer pieno
jz inibisci ;se pieno pongo in attesa la periferica di input
accetta: ;altrimenti invia dato
movb #1,flag ;pongo il flag=1 (buffer pieno) inb input,buffer ;carico dato nel buffer
start input ;abilito device a generare un nuovo dato jnim output,sbloccao ;se periferica di output e' in attesa la sblocco
jmp fineinp ;termina
inibisci: clrim input ;pone perif. input in attesa (buffer pieno)
fineinp: pop r0 ;fine driver
rti ;ritorno da interruzione
sbloccao:setim output ;sblocco periferica output jmp fineinp
;DRIVER DI OUTPUT
;Preleva dati dal buffer se questo e' vuoto pone in attesa la periferica
;di output 0->IM, sblocca (se in attesa) la periferica di input 1->IM driver 7,700h ;Il driver della periferica di IVN=7
;inizia dall'indirizzo 700h poutput:push r0 ;salva contenuto di R0
movb flag,r0 ;carica flag in R0 cmpb #0,r0 ;il buffer e' vuoto?
jz blocca ;se vuoto pongo in attesa la periferica di output consuma:
outb buffer,output ;altrimenti invio dato alla periferica di output movb #0,flag ;pongo flag=0 (buffer vuoto)
start output ;abilito perif. output a consumare il dato jnim input,sblocca ;se perif. di input 'in attesa' la sblocco jmp esci ;termina
blocca: clrim output ;blocco perif. output (buffer vuoto)
esci: pop r0 ;termina prog.
rti ;ritorna da interruzione
sblocca:setim input ;sblocco input jmp esci
;FINE DRIVER DI OUTPUT
end ;FINE PROGRAMMA
Costo aggiuntivo di un’operazione di I/O gestita tramite interruzioni
Come nel precedente esempio, si ha un processore a 2GHZ e un hard disk che trasferisce dati in blocchi da 4 longwords con un throughput max di 16 MB/s. Si ipotizzi che il costo aggiuntivo per ogni trasferimento, tenendo conto delle interruzioni, è pari a 500 cicli di clock. Si trovi la frazione del processore utilizzata nel caso in cui l’hard disk stia trasferendo dati per il 5% del suo tempo.
Frequenza di interrogazione=16 Mb/sec =1 M=10 6 accessi/sec 16 byte/accesso
Cicli per secondo spesi= 500 * 106
% processore utilizzato= 500 * 106 = 25%
2000 * 106
Frazione del processore utilizzata in media=25 % * 5 %= 1,25%
La gestione dell’I/O tramite interrupts solleva il processore dal peso di attendere
il verificarsi degli eventi di I/O.
Il costo aggiuntivo può essere comunque intollerabile se i dispositivi con cui si
interagisce hanno a disposizione una
elevata larghezza di banda.
Un esempio già noto…
Una stanza e’ monitorata da 4 sensori di temperatura, i quali sono pilotati da un PD32. Quest’ultimo controlla costantemente che il valor medio della temperatura rilevata nella stanza sia compreso tra i valori [Tmin-Tmax]. Nel caso in cui il valor medio della temperatura non cada in tale intervallo, il microprocessore inviera’ un segnale di allarme su un’apposita periferica (ALARM). Il segnale d’allarme utilizzato e’ il valore 1 codificato con 8 bit. Se la temperatura ritorna all’interno dell’intervallo [Tmin-Tmax], la CPU invia sulla periferica il valore 0.
I sensori ritornano la temperatura misurata come un numero intero ad 8 bit, usando i decimi di gradi Celsius come unita’ di misura.
Scrivere il codice assembly per il controllo dei sensori di temperatura e della periferica di allarme… utilizzando il meccanismo delle interruzioni vettorizzate (piuttosto che il polling + busy wait).
Il codice (1)
org 400h ;INIZIO PROGRAMMA sensore1 equ 0h ; indirizzo sensore1
sensore2 equ 1h ; indirizzo sensore2 sensore3 equ 2h ; indirizzo sensore3 sensore4 equ 3h ; indirizzo sensore4
alarm equ 4h ; indiririzzo periferica allarme
lowbound equ 200 ; T-min espresso in decimi di gradi Celsius upbound equ 300 ; T-min espresso in decimi di gradi Celsius
media dl 0 ; valore medio della temperatura rilevato baseadd equ 2000h; buffer contenente la temperatura misurata
device dl 0 ; indirizzo ultimo sensore che ha acquisito switch db 0 ; valore da spedire sulla periferica d’allarme state db 0 ; stato allarme (0=off, 1=on)
code ;inizio istruzioni main:
;...
jsr init
;...
loop: jmp loop ;trucco per simulare il codice sul PD32, la periferica è libera per eventuali elaborazioni
Il codice (2)
; subroutine di inizializzazione delle periferiche e avvio acquisizione init:
push r0 push r1
; calcola il centro dell'intervallo [Tmin-Tmax] ...
movl #lowbound, R0 ; addl #upbound, R0 ;
asrl #1, R0 ; e lo memorizza in R0 movl #baseadd,R1
movl R0, (R1) ; aggiorna i buffer dei 4 movl R0, 4(R1) ; sensori con il valor medio movl R0, 8(R1) ; dell’intervallo
movl R0, 12(R1) ;
movl R0, media ; inizializza la media
movb #0,state ; state memorizza lo stato (IN=0, OUT=1) SETIM sensore1 ;
SETIM sensore2 SETIM sensore3
SETIM sensore4 ; abilita i sensori a inviare interruzioni
CLRIM alarm ; blocca la periferica d’allarme che al momento non serve
Il codice (3)
START sensore1;
START sensore2;
START sensore3;
START sensore4; avvia l’acquisizione dei dati dai sensori di temp.
pop r1 pop r0 ret
; fine subroutine init
; DRIVERS
driver 0, 1600h ; periferica con IVN 0 ha driver allocato a partire dall’ind 1600h movl #sensore1, device
jsr GET rti
driver 1, 1650h
movl #sensore2, device jsr GET
rti
driver 2, 1700h …; … e 3
Il codice (4)
driver 4, 1800h
OUTB SWITCH, alarm ;invia il valore di switch sul buffer di alarm start alarm ;avvia il consumo del dato
clrim alarm ;disabilita ulteriori interrupts della periferica rti
; SUBROUTINE GET: ACQUISIZIONE DATI DALLA PERIFERICA IL CUI IND. E’
; E' SPECIFICATO NELLA VARIAB. DEVICE GET: PUSH r0
push r4 push r5
movl #baseadd, R0 movl device,r5
asll #2,r5 ; r5=device*4
ADDL r5, R0 ; r0=baseadd+device*4
asrl #2,r5 ;ripristina R5 all’address del device
INL r5, (R0); preleva il valore e lo mette in RAM nel corrispondente buffer START r5 ; avvia nuova acquisizione
Il codice (5)
MOVL media, R5 ; carico la media aggiornata in R5 movb state, R4
CMPL #upbound , R5
JNC OUT ; upbound <= R5 CMPL #lowbound, R5;
JC OUT ;lowbound > R5
; altrimenti siamo nell'intervallo [TMIN-TMAX]...
CMPb #0, R4 ; verifico se lo stato era IN=0 o OUT=1
JNZ eraout ;
exit: pop r5 pop r4 pop r0 RET
eraout: MOvb #0 ,switch SETIM alarm movb #0, state jmp exit
OUT: CMPb #0, R4 ; verifico se lo stato era IN=0 o OUT=1 JZ erain ;
jmp exit
Il codice (6)
erain: MOVb #1 ,switch SETIM alarm movb #1, state jmp exit
; aggiorna la media in base ai valori presenti nelle 4 longwords a partire da baseadd NEWMEDIA:
PUSH R0 PUSH R1
MOVL #baseadd,R1 XORL R0,R0
ADDL (R1),R0 ADDL 4(R1), R0 ADDL 8(R1), R0 ADDL 12(r1), R0 ASRL #2, R0 MOVL R0, media POP R1
POP R0 RET