Architettura dei calcolatori Argomenti del corso Breve presentazione del corso Docenti: Davide Ancona (titolare) Giuseppe Ciaccio (esercitatore) CFU: 12, circa 96 h ripartite su 48 lezioni Esame: uno scritto finale, orale opzionale in casi eccezionali (modifica voto + o 3 punti) Codici binari (16 h circa) Circuiti (16 h circa) Componenti HW (8 h circa) Macchine CISC (8 h circa) Microprogrammazione (10 h circa) Macchine RISC (10 h circa) Aspetti più avanzati (10 h circa) Miglioramento prestazioni (10 h circa) Linguaggi ad alto livello (8 h circa) 1 2 Livelli di astrazione Strumenti e materiale Codici binari Linguaggi ad alto livello Macchine RISC, CISC, aspetti avanzati Microprogrammazione, miglioramento delle prestazioni aula web: 2 forum, registro lezioni, quiz, altro materiale pagina web: testi esami scritti, risposte e soluzioni, appunti, altre info dispense: bastano per l'esame libri: solo per approfondire Circuiti, componenti HW 3 spiegazioni: meglio prima che finiscano le lezioni ... 4 Integrazione con altri insegnamenti Codici binari Programmazione e algoritmi e strutture dati: una visione più a basso livello aiuta a capire meglio certi meccanismi legame tra C e linguaggi macchina Insieme di tutte le codifiche binarie succ({0,1}) = tutte le successioni di bit finite e infinite (numerabili) Def. più formale: insieme di tutte le funzioni parziali c:N{0,1} tali che per ogni n,mN se c(n) definito e m<n, allora c(m) definito Sistemi operativi: soprattutto per gli aspetti avanzati 5 Un po' di notazione 6 Lunghezza di una codifica Una conveniente rappresentazione (specialmente nel caso finito) Sia indef(c)={i|cod(i) indefinito} c = bN-1bN-2 ... b0 c(i)=bi per i=0..N-1, c(i) indefinito per i>N-1 |c| = min(indef(c)) se indef(c) |c| = + se indef(c)= l'ultimo bit a destra ha pedice 0 (e non 1) e viene detto bit meno significativo Esempi: |1001| = 4, |bN-1bN-2 ... b0| = N | | = 0, |...1...1010| = + l'ultimo bit a sinistra ha pedice N-1 (se ci sono N bit) e viene detto bit più significativo 7 8 Codici binari X .... decod cod succ({0,1}) 101 0 .... Codici binari (formalizzazione) ogni elemento in X deve avere (almeno) una codifica ogni successione in succ({0,1}) deve codificare (al più) un elemento in X Negli esempi X = {, , , , , } cod:Xparti(succ({0,1})-{} funzione totale Es.: cod()={10,010} spesso per praticità è una funzione da X in succ({0,1}) Es.: cod()=10 10, 010 vengono dette codifiche o configurazioni 9 10 Codifiche valide/non valide Codici binari (formalizzazione) Negli esempi X = {, , , , , } decod:succ({0,1})X funzione parziale Es.: decod(110)= decod(111) indefinito codifica senza perdita di informazione (lossless) xX, ccod(x) decod(c)=x se tale proprietà non è verificata la codifica è lossy (con perdita di informazione) codifiche valide insieme V = { c | decod(c) definito} codifiche non valide: NV = { c | decod(c) indefinito} quindi V NV = succ({0,1}) e V NV = 11 12 Lunghezza fissa o variabile? Codici binari a lunghezza fissa Presupposto: ci limitiamo a succesioni di bit di lunghezza finita e non nulla. lunghezza fissa: cV, |c|=N N costante detta lunghezza del codice se N è la lunghezza, sono codificabili al più 2N elementi proprietà di base: lunghezza variabile: c1, c2V tali che |c1||c2| Scelta più pratica: lunghezza fissa. Le celle di memoria hanno tutte la stessa dimensione! 13 Codifica dei numeri 20 = 1 21 = 2 2x * 2y = 2x+y 2x / 2y = 2x-y, quindi 2-x = 1 / 2x 2x+1 2x = 2x i=h..k=2h + 2h+1 + ... + 2k = 2k+1 - 2h Codifica dei numeri naturali tutte le codifiche sono a lunghezza fissa N = {0,1,2,...} codificabili solo degli intervalli finiti Si usa un unico tipo di codifica realizzazione delle operazioni decod(bN-1bN-2 ... b0) = i=0..N-1 2i*bi addizione (algebrica), moltiplicazione e divisione confronto (=, , <, , >, ) conversioni stessa codifica, ma lunghezza diversa codifiche diverse 14 Es.: decod(01101) = 1*20 + 0*21 + 1*22 + 1*23 + 0*24 = 1 + 4 + 8 = 13 15 16 Codifica dei numeri naturali Codifica dei numeri naturali cod(n) = addizione (2 addendi): si usa la seguente tabella: for i = 0..N-1 bi = n % 2 addendo 1 addendo 0 0 0 0 1 1 1 1 n = n / 2 return bN-1bN-2 ... b0 n deve appartenere all'intervallo [0..2N-1] 2 riporto precedente riporto risultato 0 0 0 0 0 1 0 1 1 0 1 0 1 1 1 0 0 0 0 1 0 1 1 0 1 0 1 0 1 1 1 1 17 18 Codifica dei numeri naturali Codifica dei numeri naturali Esempio di addizione overflow nell'addizione: 01101 + (addendo 1) dovuto alla lunghezza fissa del codice 00111 = (addendo 2) il risultato può cadere fuori dall'intervallo di rappresentabilità 011110 10100 (riporti) (risultato) il primo riporto è sempre 0 sottrazione: meno interessante, visto che poi si codificano gli interi il calcolo parte dalla cifra meno significativa l'ultimo riporto serve per l'overflow 0 ok 1 overflow 19 20 Codifica dei numeri naturali Codifica dei numeri naturali moltiplicazione e divisione moltiplicazione per 2k: Vediamo solo un caso facile: shift aritmetico a sinistra di k posizioni moltiplicazione e divisione per potenze di 2 Es.: 00010110 Es.: 10110000 001011 * 000100 = 101100 i 3 bit più significativi vengono persi. Se uno dei bit è 1 overflow 21 22 Codifica dei numeri naturali Codifica dei numeri naturali divisione intera per 2k: confronto shift aritmetico a destra di k posizioni aN-1...a0 < bN-1...b0: Es.: 01010110 for i = N-1..0 00001010 sposto tutti i bit a sinistra di 3 posizioni le 3 posizioni rimaste libere vengono completate con bit a 0 aggiungo 2 zeri a destra e perdo i 2 più significativi tutte le codifiche con un solo bit a 1 sono potenze di 2 (con k=3) (con k=3) sposto tutti i bit a destra di 3 posizioni le 3 posizioni rimaste libere vengono completate con bit a 0 if ai != bi return ai < bi return false i 3 bit meno significativi che vengono persi corrispondono al resto della divisione 23 24 Codifica dei numeri naturali Codifica dei numeri interi modifica della lunghezza espansione: aggiungo 0 a sinistra Z={0,1,-1,2,-2,...} Esistono diversi codici Es.: 10011 00010011 da 5 a 8 bit aggiunti compressione: levo 0 a sinistra Es.: 00011011 posso scendere fino a 5 bit eliminabili modulo e segno complemento a 1 complemento a 2 eccesso 2N-1 Intervalli [-(2N-1-1),2N-1-1] simmetrico, 2 zeri [-2N-1,2N-1-1] antisimmetrico, 1 zero 25 Modulo e segno Modulo e segno Intervallo di rappresentabilità Si aggiunge il segno a sinistra bN-1 bN-2 ... b0 Es. codZ(+7)=+111, codZ(-7)=-111 26 Problema: solo 2 simboli: 0 e 1 bit di modul segno o Il modulo codifica un naturale su N-1 bit Quindi max del modulo = 2N-1-1 e intervallo = [-(2N-1-1),2N-1-1] Notare che cod(0) = {10...0,00...0} Soluzione: + 0, - 1 Es. codZ(+7)=0111, codZ(-7)=1111 decodZ(0101)=+decodN(101)=+5 decodZ(1110)=-decodN(110)=-6 27 28 Modulo e segno Modulo e segno addizione algebrica complicata segno concorde addizione dei moduli Es.: 10110 + 10011 = 11001 segno: vedi la tabella i moduli si moltiplicano/dividono Regola del segno segno discorde moltiplicazione e divisione più semplici * 0 1 confronto tra i moduli sottrazione dei moduli: max - min il segno è quello del modulo maggiore Es.: 10100 + 00011 = 10001 cambio di segno ovvio confronto prima confronto i bit di segno: 0 > 1 se sono concordi 0: come per i naturali 1: il maggiore è quello col modulo minore 1 1 0 29 30 Modulo e segno 0 0 1 Modulo e segno modifica della lunghezza espansione: aggiungo 0 a sinistra del modulo Es.: 10011 10000011 da 5 a 8 bit aggiunti compressione: levo 0 a sinistra del modulo Es.: 10000011 posso scendere fino a 3 bit eliminabili 31 32 Complemento a 1 Complemento a 1 comp(0) = 1, comp(1) = 0 decodZ(0bN-2...b0) = decodN(bN-2...b0) positivi decodZ(1bN-2...b0) = come la codifica dei naturali - decodN(comp(bN-1...b0)) negativi (complementazione bit a bit) Es.: decodZ(1110) = - decodN(0001) = -1 codZ(-n) = comp(codN(n)) Es.: codZ(3) = comp(codN(3))=comp(011)=100 zero: codZ(0) = {0...0,1...1} bit di segno: 1 -, 0 + (zero a parte) 33 intervallo di rappresentabilità max = decodZ(01...1) = 2N-1 1 min = decodZ(10...0) = - (2N-1 1) Complemento a 1 Complemento a 1 operazioni aritmetiche realizzazione diretta non semplice (a parte i non negativi) cambio di segno: complementazione confronto: prima confronto i bit di segno: 0 > 1 se concordi, confronto come naturali 34 modifica della lunghezza espansione/compressione per i positivi: come per i naturali espansione/compressione per i negativi: inserisco/cancello 1 Es.: 1001 111001 da 4 a 6 bit Es.: 11110101 10101 da 8 a 5 bit eliminabili 35 36 Complemento a 2 Complemento a 2 positivi come la codifica dei naturali decodZ(0bN-2...b0) = decodN(bN-2...b0) decodZ(1bN-2...b0) = negativi (complementazione più 1) - decodN(comp(bN-1...b0) + 0..01) codZ(-n) = comp(codN(n)) + 0...01 (n naturale) Es.: decodZ(1110) = - decodN(0010) = -2 Es.: codZ(-3) = comp(codN(3)) + 001 = = comp(011) + 001 = 101 zero: codZ(0) = 0...0 bit di segno: 1 -, 0 + 37 intervallo di rappresentabilità max = decodZ(01...1) = 2N-1 1 min = decodZ(10...0) = - 2N-1 Complemento a 2 Complemento a 2 addizione: come per i naturali (escludendo il possibile riporto) 1001 + 1110 + 1000 = 1111 = calcolo dell'overflow 0001 1101 se segni discordi: mai overflow se segni concordi: segno risultato concorde segno risultato discorde 38 segno discorde overflow ok segno concorde ok overflow 39 40 Complemento a 2 Complemento a 2 moltiplicazione e divisione realizzazione diretta non semplice (a parte i non negativi) cambio di segno: complementazione + 1 (attenzione all'overflow per 10...0) prima confronto i bit di segno: 0 > 1 se concordi, confronto come naturali espansione/compressione per i positivi: come per i naturali espansione/compressione per i negativi: inserisco/cancello 1 Es.: 1001 111001 da 4 a 6 bit confronto: modifica della lunghezza Es.: 11110101 10101 da 8 a 5 bit eliminabili 41 42 Eccesso 2N-1 codZ(n) = codN(n + 2N-1) decodZ(c) = decodN(c) 2N-1 intervallo di rappresentabilità Eccesso 2N-1 realizzazione diretta non semplice max = decodZ(1...1) = 2 - 1 2 cambio di segno: complementazione + 1 (attenzione all'overflow per 00...0) min = decodZ(0...0) = 2N-1 N addizione, moltiplicazione e divisione N-1 =2 N-1 1 1 +, 0 - (al contrario degli altri) 43 confronto: come il codice per i naturali modifica della lunghezza: meglio convertire in complemento a 2, modificare la lunghezza e poi riconvertire 44 Conversioni Conversioni complemento a 2 eccesso 2N-1 0aN-2...a0 0aN-2...a aN-1aN-2...a0 comp(aN-1)aN-2...a0 modulo e segno complemento a 1 1aN-2...a0 1comp(aN-2...a0) complemento a 2 complemento a 1 0aN-2...a0 0aN-2...a0 1aN-2...a0 1aN-2...a0-1 con l'eccezione 10...0 101...1 N bit N+1 bit 45 46 Codifica dei razionali/reali Codifica dei razionali/reali Q={ p/q | pZ, qN+} R={ limn+ s | s succ. di Cauchy in Q} X = intervallo limitato Problema: codici con perdita di informazione! Codifica approssimata: in un intervallo finito esistono infiniti razionali e reali: Es.: 1/n [0..1] per ogni n N I codici hanno lunghezza fissa Es.: decod(cod(0.2)) 0.2 + 47 48 Codici in virgola fissa Codici in virgola fissa Sistema decimale usuale: Es.:936.3729 102 100 10-1 Soluzione (semplice): posizione fissata a priori 10-4 Passando alla base 2: Posizione specificabile in vari modi. La virgola separa la posizione 20 dalla Es.: 101.1001 22 20 2-1 posizione 2-1. 2-4 decod(101.1001) = 22 + 20 + 2-1 + 2-4 = 5.5625 49 Per ora tralasciamo i valori negativi. 50 Codici in virgola fissa Codici in virgola fissa Fissiamo N = 7 e c = 1011001 2 cifre intere: decodifica: decod(bk+N-1...bk) = i=k..k+N-1 2i * bi 10.11001 2 cifre frazionarie: 10110.01 cifra più significativa corrisponde a 23: k = esponente bit meno significativo Es.: N = 5, k = -3 1011.001 Problema: come rappresento la virgola? decod(10110) = 21 + 2-1 + 2-2 = -4 cifra più significativa corrisponde a 2 : = 2 + ½ + ¼ = 2.75 101.1001 51 52 Codici in virgola fissa Codifica parte frazionaria codifica: N = I+F, I parte intera, F frazionaria codR(F)(n) = for i = -1..-F codR(I,F)(n)=codN(I)(n) codR(F)(n-n) n = n * 2; bi = if n < 1 then 0 else 1 codifica parte intera su I bit codifica parte frazionaria su F bit n = if n < 1 then n else n - 1 return b-1b-2 ... b-F 53 54 Codifica in virgola fissa Errore di approssimazione = | n decodR(I,F)(codR(I,F)(n)) | Es.: codR(3,4)(5.75) = 1011100 decodR(3,4)(1011100) = 22+20+2-1+2-2= codR(3,4)(5.75) = 1011100 = | 5.75 5.75 | = 0 (esatta) = 4+1+1/2+1/4 = 5.75 codR(1,3)(0.1) = 0000 codR(1,3)(0.1) = 0000 = | 0.1 0 | = 0.1 (per difetto) decodR(1,3)(0000) = 0 55 codR(1,3)(0.1) = 0001 = | 0.1 0.125 | = 0.025 (per eccesso) 56 Approssimo per difetto o per eccesso? Approssimazione Codifica di 0.1, 1 bit intero, 3 frazionari 0000 approssimo per difetto b-1...b-Fb-F-1 (codifica parte frazionaria) = 0.1 0001 approssimo per eccesso bit meno significativo bit in avanti serve solo per approssimare = 0.025 Approssimazione migliore: b-F-1=0 b-1...b-F (approssimo per difetto) max i=-F-2..-F-N-12i = 2-F-1-2-F-N-1 NN+ quella con errore minore quindi max< 2-F-1 Basta guardare un bit in avanti nel procedimento di codifica 57 58 Approssimazione Approssimazione b-F-1=1 b-1...b-F +0..01 (approssimo per F bit eccesso) Una visione grafica d = decodR(F)(b-1...b-F) max decodR(F)(b-1...b-F +0..01)-decodR(F+1)(b-F ...b-F1) = 2 -2 1 -F-1 =2 approssimato per difetto o per eccesso approssimato 2-F per eccesso approssimato per difetto -F-1 Attenzione: in b-1...b-F +0..01 il riporto potrebbe propagarsi alla parte intera n1 d 59 n3 n2 -F d+2-F-1 d+2 2-F-1 60 Codifiche infinite Overflow e underflow 2 ovvio ... 1/3 = 0.333...333... ovvio anche questo val max rappresentabile con =0 0.2 meno ovvio: decodR(3,4)(1111111) = 23-2-4 0.2 * 2 = 0.4 I=3, F=4 val min positivo rappresentabile con =0 0.4 * 2 = 0.8 0.8 * 2 = 1.6 decodR(3,4)(0000001) = 2-4 0.6 * 2 = 1.2 1111111 + 0000001 = overflow 0.2 * 2 = 0.4 61 ..... Codifiche in virgola mobile 0000001 * 0001000 = underflow 62 Codifiche in virgola mobile base 10: 1.812 * 10-3 Es.: I=1, F=3 1.812 m virgola fissa in base 10 1812 m = 1.812 Km = 1.812 * 103 m potenza di 10 base 2: 1.011 * 2-3 0.01812 m = 1.812 cm = 1.812 * 10-2 m virgola fissa in base 2 2 181.2 m = 1.812 hm = 1.812 * 10 m -3 1011 -3 0.001812 m = 1.812 mm = 1.812 * 10 m potenza di 2 virgola fissa, I=1, F=3 base fissata, riporto solo l'esponente 11101 1011 63 esponente in complemento a 2 con N=5 64 Normalizzazione Normalizzazione Quindi: Es. di formato: 111001 1100 cod(2-7*1.5)={111001 1100, 111010 0110, 111011 0011} mantissa con I=1, F=3 esponente in complemento a 2 con N=6 e = decodZ(111001) = -7 Meglio se cod è una funzione. m = decodR(1,3)(1100) = 1.5 Basta imporre che m sia normalizzata Tipicamente: 20 m < 21 decod(111001 1100)=2e *m=2-7*1.5 Più in generale: decod(111010 0110)=2-6*1.5/2=2-7*1.5 decod(111011 0011)=2-5*1.5/4=2-7*1.5 65 2k m < 2k+1 per un certo k fissato Normalizzazione 66 Calcolo della codifica Se 1 m < 2 Con normalizzazione 1 m < 2 -7 cod(2 *1.5)=111001 1100 cod(n)=codZ(e) codR(F)(-1+n/2e) Ottimizzazione: visto che 1 m < 2, dove e = log2(n) infatti la codifica di m sarà sempre della forma e n=2 *m 1b-1..b-F m=n/2 0 log2(n)-e < 1 questo bit è superfluo e viene quindi omesso 67 e esclusione del primo bit 1 n/2e < 2 e= log2(n) codZ dipende dalla codifica scelta per e F = lunghezza della mantissa 68 Calcolo della decodifica Codifica dello zero Con normalizzazione 1 m < 2 2e*m=0 non ha soluzioni per 1 m < 2 decod(bN-1..b0b-1..b-F)=2e*m Eccezione: dove e=decodZ(bN-1..b0) cod(0)=0..00..0 configurazione 0..0 inutilizzata per e m=decodR(F)(b-1..b-F)+1 codice eccesso 2N-1 evita buchi 69 70 Numeri negativi Codifica dei caratteri Codifica più utilizzata: modulo e segno b bN-1..b0 b-1..b-F insieme di simboli, interpretazione puramente sintattica (a parte i caratteri di controllo) codifica di m bit di segno Cosa sono i caratteri: Es. caratteri stampabili: 'a' 'A' '7' '@' '#' codifica di e Es. caratteri di controllo: '\n' (new line) '\t' (tab) 71 Codifica meno problematica rispetto ai numeri: meno operazioni e più semplici 72 Codifica dei caratteri Codice ASCII Esistono vari codici: Codifica delle lettere: immersione in un intervallo di N, ordine preservato (sia per le ASCII, unicode, EBCDIC,... minuscole che per le maiuscole) Esempio: ASCII cod('a')<cod('b')<...<cod('z') American Standard Code for Information Interchange cod('A')<cod('B')<...<cod('Z') Lunghezza fissa: 7 bit cod('b')-cod('a')=0000001, ... cod('B')-cod('A')=0000001, ... 73 Codice ASCII cod('a')-cod('A')=cod('b')-cod('B')=... 74 Cifre: caratteri o numeri? Attenzione: '0'0, '1'1,...,'9'9 Codifica delle cifre: immersione in un intervallo di N, ordine preservato '5' carattere (simbolo stampabile) cod('0')<cod('1')<...<cod('9') 5 numero cod('1')-cod('0')=0000001 Si usa codifica diversa: ... cod('5')=0110101 (7 bit) cod('9')-cod('8')=0000001 cod(5)=0000000000000101 (16 bit) 75 76 Stampa di un numero Base 2 base 10 1.Conversione da base 2 a base 10 Per semplicità solo caso n>0 (N=8) 2.Conversione da cifra-numero a cifracarattere conv2to10(n)= 3.Stampa del carattere while (n>00000000) i=0 ci = n % 00001010 /* resto */ n = n / 00001010 /* quoziente */ i = i + 1 77 Cifra-numero cifra-carattere return ci-1...c0 78 Rilevazione di errori Cifra-numero su 8 bit, cifra-carattere su 7 convChar(b7...b0)= Consideriamo un codice a lunghezza fissa return b6...b0 + cod('0') voglio capire se si sono verificati errori. Problema: leggo/ricevo configurazione c numero errori = numero bit alterati Assumendo codice ASCII: convChar(b7...b0)= Es.: una cella contiene 0011 lettura n.1: ottengo 0011 (0 errori) return b6...b0 + 0110000 lettura n.2: ottengo 1010 (2 errori) 79 lettura n.3: ottengo 0001 (1 errore) 80 Distanza di Hamming Rilevazione di al più k errori Numero di bit diversi a parità di posizione Cella contiene cV, viene letto c' H(b1...bN,b'1...b'N)=i=1..N|bi-b'i| Numero errori commessi = H(c,c') bi=b'i |bi-b'i|=0 Codice a rilevazione di al più k errori: bib'i |bi-b'i|=1 se 1H(c,c')k allora c'NV Condizione necessaria, ma non sufficiente: quindi 0H(b1...bN,b'1...b'N)N Es.: H(01010,01010)=0, H(11100,01001)=3, H(10010,01101)=5 il codice deve avere una certa ridondanza 81 82 Ridondanza Codici ridondanti in ogni caso R 1 controllo di c': mi accorgo di errori solo se c'NV (assumendo che cV) N NV = { c {0,1} | decod(c) indefinito} V = { c {0,1}N | decod(c) definito} N V NV = {0,1} e V NV = Ridondanza di un codice R 2 codice ridondante: le configurazioni non valide di lunghezza N sono almeno tante quante quelle valide Ricorda: |V|+|NV| = 2N R =(|V|+|NV|)/|V|=2N/|V| tutte le configurazioni R = 1 tutte le configurazioni di lunghezza N sono valide R2 ! 2N/|V|2 ! (|V|+|NV|)/|V|2 ! 83 numero configurazioni valide |NV||V| 84 Ridondanza necessaria Ridondanza non sufficiente Teorema: se riesco a rilevare al più un errore, allora R2 Ridondanza non sufficiente per rilevazione errori Sia V={c1,...,cv}, H1(ci)={c | H(c,ci)=1} Es.: N=3, V={000,001,010,011} H1(ci)V= quindi S=i=1..vH1(ci)"NV R=23/|V|=8/4=2 per ogni c in S, nc=card{ci | H(c,ci)=1} codice ridondante, Fatti: |H1(ci)|=N, ncN ma se, per esempio, c=000 e c'=001 |V|*N=#i=1..v|H1(ci)|=#cSnc#cSN=|S|*N non mi accorgo dell'errore 85 quindi V"S"NV Condizione suff. e necessaria non riesco a rilevare neanche un errore! 86 Condizione equivalente Teorema: rilevo al più k errori ! c,c'V cc' c,c'V cc' cV 0<H(c,c')k H(c,c')>k ( ) se per assurdo c,c' V c c' e H(c,c') k allora non riesco a rilevare al più k errori ($) sia cV, cc' e H(c,c')k, allora necessariamente c'NV, quindi riesco a rilevare l'errore H(c,c')>k ! c' NV c' k c tutte configurazioni non valide 87 88 Disuguaglianza triangolare Disuguaglianza triangolare Vale anche H(c1,c2)+H(c2,c3) 2N-H(c1,c3) H(c1,c3)H(c1,c2)+H(c2,c3) Infatti, per ogni posizione i tale che c1ic3i Infatti, per ogni posizione i tale che c1i=c3i c2i=c1i ! c2ic3i c2i=c1i ! c2i=c3i quindi |c1i-c3i|=1=|c2i-c1i|+|c2i-c3i| quindi |c2i-c1i|+|c2i-c3i|=0 oppure 2 e per ogni i tale che c1i=c3i H(c1,c2)+H(c2,c3) |c1i-c3i|=0|c2i-c1i|+|c2i-c3i| 89 Codici di Hamming H(c1,c3)+2(N-H(c1,c3))=2N-H(c1,c3) 90 Codici di Hamming Problema: codice con R=1, voglio poter rilevare al più 1 errore Tecnica del bit di parità Es.: c=100110 1 Basta aggiungere 1 bit: 2N/|V|=1 2N+1/|V|=2 bit di dato Ma la ridondanza non è sufficiente... Controllo: se il numero totale di bit a 1 è pari, allora cV, altrimenti cNV Bisogna trovare una tecnica per cui 1. H(c1,c2)>1 per ogni c1,c2V, c1c2 2. cNV verificabile semplicemente bit di parità determinato dai bit di dato 91 Facilmente realizzabile tramite logica circuitale, usando porte XOR (vedi parte 92 su circuiti combinatori) Codici di Hamming 1 bit di parità Codici di Hamming rilevabile 1 errore Rilevazione di al più 2 errori Infatti c1,c2V c1c2 H(000000 0,000001 1)=2 1 bit di parità non basta c1,c2V c1c2 Attenzione: numero bit di parità necessari cresce con la lunghezza N del codice a differenza dei codici di Hamming a 1 bit c1V H(c1,c2)>1 c1 contiene numero pari di bit a 1 H(c1,c2)=1 c2 contiene numero dispari di bit a 1 c2 NV H(c1,c2)>2 93 94 Rilevazione errori e ridondanza Rilevazione errori e ridondanza Sia C codice non ridondante (1R<2) di lunghezza N, se aggiungo 1 bit di parità ottengo C' con R'=2N+1/|V'|=2R<4 Sia C tale che rileva al più 2 errori, sia V={c1,...,cv}, S=i=1..vH1(ci)"NV Nota bene: R=2N/|V| e |V|=|V'| ij implica H1(ci)H1(cj)= infatti se Quindi la ridondanza di C' è limitata indipendentemente dal valore di N cH1(ci), H(ci,cj)H(c,ci)+H(c,cj) H(c,cj)H(ci,cj)-12 Ciò non vale per C' che rileva al più 2 errori |NV|N*|V| 95 % c H1(cj), quindi R (N*|V|+|V|)/|V|=N+1 96 Codici di Hamming a più bit Codici di Hamming a più bit Abbiamo visto che 1 bit di parità non basta per rilevare 2 errori Assumiamo quindi di avere P bit di parità Sia D(p) l'insieme delle posizioni di tutti i bit di dato che determinano il bit di parità di posizione p di posizione p1,...,pP e D bit di dato di posizione d1,..,dD Sia P(d) l'insieme delle posizioni di tutti i bit di parità che dipendono dal bit di dato di posizione d D(p)={d | pP(d)} P(d)={p | dD(p)} ossia D e P sono relazioni inverse l'una dell'altra 97 98 Codici di Hamming a più bit Codici di Hamming a più bit cV ! in c le posizioni in {p1}D(p1) hanno n. pari di bit a 1 && in c le posizioni in {p2}D(p2) hanno n. pari di bit a 1 && ... && in c le posizioni in {pP}D(pP) hanno n. pari di bit a 1 99 Dato P, troviamo un modo per determinare il numero massimo D di bit dato che possono essere gestiti da P bit di parità gli insiemi D(p) per ogni posizione di bit di parità 100 Codici di Hamming a più bit Codici di Hamming a più bit caso 1) Osservazione: se cV e H(c,c')=2 allora deve essere c'NV c' ottenuto da cV alterando 2 bit di parità 3 casi a seconda dei 2 bit alterati di posizione pi e pj (ij) 1) 2 bit di parità Se {pi}D(pi) e {pj}D(pj) verificano il controllo di parità in c allora non lo 2) 1 bit parità, 1 bit di dato 3) 2 bit di dato verificano in c' (in entrambi gli insiemi si modifica solo il bit di parità) 101 Codici di Hamming a più bit Quindi c'NV come richiesto 102 Codici di Hamming a più bit caso 2) caso 3) c' ottenuto da cV alterando 1 bit di parità di posizione p e 1 bit di dato di posizione d c' ottenuto da cV alterando 2 bit di dato di posizioni di e dj (ij) Se pP(d) allora se {p}D(p) verificano il controllo di parità in c lo verificano anche in c' (2 bit modificati) se P(di)=P(dj) allora per ogni pP(di) se Ma se esiste p'p t.c. p'P(d), allora se {p'}D(p') verificano il controllo di parità in c non lo verificano in c' (1 bit modificato) Quindi deve essere |P(d)|>1 affinché c'NV103 {p}D(p) verificano il controllo di parità in c lo verificano anche in c' (2 bit modificati) Ma se P(di)P(dj) allora esiste almeno p t.c. se {p}D(p) verificano il controllo di parità in c non lo verificano in c' (1 bit modificato) Quindi 104 deve essere P(di)P(dj) affinché c'NV Codici di Hamming a più bit Codici di Hamming a più bit Come determinare P(d)? Max numero di bit di dato D gestibile con P bit di parità |P(d)|>1 per ogni posizione d di bit dato Ogni SParti({p1,...,pP}) rappresentabile con configurazione bP...b1 di bit S ij P(di)P(dj) per ogni posizione di, dj di bit di dato funzione caratteristica o indicatrice 'S:Parti({p1,...,pP}) {0,1} D = max numero insiemi su P elementi di cardinalità maggiore di 1 D = 2P-P-1 &(isomorfismo) l'insieme vuoto 105 tutti i possibili insiemi &(isomorfismo) tutti gli insiemi con 1 elemento Codici di Hamming a più bit Quindi P(d) bP...b1 con almeno 2 bit a 1 (cardinalità deve essere maggiore di 1) Idea: P(d) cod(d) (codifica dei naturali con P bit) Quindi basta scegliere per i bit di dato posizioni diverse da 0 e potenze di 2 Le potenze di 2 sono per le posizioni dei bit di parità, la posizione 0 non si usa (si 107 parte da 1) configurazione di P bit 106 Codici di Hamming a più bit Convenzioni sul formato: P bit parità lunghezza max=P+D=2P-1 Calcolo posizioni bit di parità p1,...,pP: p1=20, p2=21,...,pP=2(P-1) Calcolo posizioni bit di parità d1,...,dD: d1=3, d2=5,...,dP=2P-1 Nota bene: le posizioni partono da 1 108 Codici di Hamming a più bit Codici di Hamming a più bit Grazie a questa convenzione Esempio con P=3 (3 bit parità) {pi}D(pi)={n | n=decod(bP+D...bi+11bi-1...b1)} DMAX=23-3-1= 4 (4 bit di dato) dove decod è la solita decodifica binaria dei naturali su P+D bit Codice a 7 bit col seguente formato: P(k)=cod(k) su P+D bit 7 Nota bene: funziona anche quando k corrisponde a un bit di parità P(p)={p} d4d3d2p3d1p2p1 (posizioni bit parità: 1,2 e 4) 6 5 4 3 2 1 P(3)={2,1},P(5)={4,1},P(6)={4,2},P(7)={4,2,1} 109 Codici di Hamming a più bit Conversione da codice non ridondante (R<2) di lunghezza D a codice di Hamming per la rilevazione di al più 2 errori. D(1)={7,5,3},D(2)={7,6,3},D(4)={7,6,5} Codici di Hamming a più bit Per rilevare al più 3 errori ci vogliono più bit e codici ancora più complessi Esempio con P=3, D=4 Il numero minimo P di bit di parità deve essere t.c. 2P-1-P<D2P-P-1 1001100V Per ogni bD...b1 valida 0101101V bD...b1 bD...b2b'3b1b'2b'1 con {b'1,...,b'P} tali che H(1001100,0101101)=3 rilevare 3 errori le posizioni in {2i-1}D(2i-1) abbiano numero 111 pari di bit a 1 per ogni i=1..P 110 codice non può 112 Correzione di al più k errori (k>0) Teorema: correggo al più k errori (k>0)! Def.: per ogni c,c' se cV e 1H(c,c')k allora non esiste c''V tale che c''c e H(c'',c')k c,c''V cc'' H(c,c'')>2k ( ) Per Teo. su rilevazione Quindi: Condizione suff. e necessaria c,c''V cc'' H(c,c'')>k c'NV: 1H(c,c') cc'. Se per assurdo c'V allora c'c e H(c',c')=0<k (imposs.) Per assurdo siano c,c''V tali che k<H(c,c'')2k. l'unica correzione possibile è c'c È sempre possibile passare da c a c'' modificando prima k bit, ottenendo c', e poi i rimanenti H(c,c'')-k bit diversi 114 113 Condizione suff. e necessaria Codici a correzione di 1 errore Considero codice a rilevazione di al più 2 errori Quindi H(c,c')=k e H(c',c'')=H(c,c'')-k2kk=k, per cui Poiché c,c'V cc' 1H(c,c')k, ma cc'', c''V e H(c',c'')k Allora è anche codice a correzione di 1 errore contro l'ipotesi Bit da correggere: ($) Supponiamo esistano c,c''V e c' t.c. 1H(c,c')k, c''c e H(c'',c')k S = {posizioni dei bit di parità sbagliati} devo modificare posizione k t.c. Per disuguaglianza triangolare H(c,c'')H(c,c')+H(c'',c')2k, contro l'ipotesi H(c,c')>2=2*1 k{p}D(p) per ogni pS k%{p}D(p) per ogni p%S 115 116 Quindi k=pSp Codici a correzione di al più 1 errore Codici a lunghezza variabile Esempio con P=3, D=4 Confronto con lunghezza fissa: Si vuole correggere 1001000 codici a lunghezza fissa più semplici, scelta naturale che riflette l'organizzazione fisica della memoria (celle di lunghezza fissa) codici a lunghezza variabile permettono di risparmiare bit a fronte di una maggiore complessità In {1}D(1)={1,3,5,7} n. bit a 1 è dispari NO In {2}D(2)={2,3,6,7} n. bit a 1 è dispari NO In {4}D(4)={4,5,6,7} n. bit a 1 è pari OK Quindi S={1,2} e il bit da correggere è in posizione k=1+2=3 117 118 Codifica delle istruzioni Codici a lunghezza variabile Un semplice esempio: Due esempi di applicazione: codifica delle istruzioni macchina compressione dei dati 119 codifica istruzioni: a lunghezza fissa (16 bit) 4 formati di istruzioni: a 0, 1, 2 o 3 operandi codifica di un operando: a lunghezza fissa (4 bit) 120 Codifica delle istruzioni Codifica delle istruzioni Una soluzione semplice: codice operativo a lunghezza fissa La codifica di un'istruzione è formata da due parti. Alcuni tipi di istruzione usano 3 operandi, ogni operando è codificato con 4 bit 16 bit codifica operandi almeno 4*3=12 bit codice operativo operandi codice operativo al più 16-12=4 bit 16 bit codifica del tipo di istruzione codice operativo operandi 4 bit 12 bit 121 Codifica delle istruzioni 122 Codifica delle istruzioni codice operativo lunghezza fissa 4 bit 4 posso codificare al più 2 =16 tipi diversi di istruzione Problema: spreco dei bit Una soluzione che non spreca bit: codice operativo a lunghezza variabile La lunghezza dipende dal numero di operandi richiesto dal tipo di istruzione Numero operandi Lunghezza codice operativo 4 bit per ogni istruzione a 2 operandi 8 bit per ogni istruzione a 1 operando 0 16 1 12 2 8 3 4 Domanda: quanti tipi di istruzioni a 3 operandi riesco a codificare? Devono essere meno di 24 12 bit per ogni istruzione a 0 operandi 123 124 Codifica delle istruzioni Codifica delle istruzioni Una possibile soluzione all'ambiguità Problema dell'ambiguità codice op. a 4 bit: b3b2b1b0 con b3b2b1b0 1111 0000110011110101 Istruzione a 3 operandi con codice operativo 0000? codice op. a 8 bit: 1111b3b2b1b0 con b3b2b1b0 1111 Istruzione a 2 operandi con codice operativo 00001100? etc. codice op. a 12 bit: 11111111b3b2b1b0 con b3b2b1b0 1111 Devo trovare un modo per evitare questa ambiguità codice op. a 16 bit: 125 Codifica delle istruzioni 111111111111b3b2b1b0 (b3b2b1b0 qualsiasi) Compressione dei dati Totale tipi di istruzioni codificabili: Un semplice esempio: 4 considero file che contiene solo i simboli 4 A,E,I,O,U 4 Uso codice a lunghezza fissa non ridondante per codificare A,E,I,O,U 2 -1 con 3 operandi 2 -1 con 2 operandi 2 -1 con 1 operando 4 2 con 0 operandi 26-3=61 in totale rispetto alle 16 rappresentabili con codici operativo di lunghezza fissa 4 126 N=3 (22<5<=23) 127 Quindi se file contiene L caratteri la sua dimensione è 3L bit 128 Compressione dei dati Compressione dei dati Se la frequenza di ogni simbolo è diversa posso comprimere il file se passo a lunghezza variabile Una possibile soluzione (anche se non ottimale...) A 0, E 10, O 110, U 1110, U 1111 Esempio frequenze: Non c'è ambiguità ogni codifica non è prefisso di altre codifiche f(A)=0.35,f(E)=0.25,f(O)=0.21,f(I)=0.15, f(U)=0.04 Assegno configurazioni di lunghezza minore a simboli di frequenza maggiore 129 Compressione dei dati 130 Rapporto di compressione Lunghezza del file compresso: L=numero simboli codificati nel file In realtà L non serve perché il dato interessante è il rapporto di compressione S=insieme dei simboli (3*L/2.24*L)1.34 l(s) lunghezza del codice che codifica s Oppure la percentuale di spazio risparmiato: (sS l(s) * f(s))*L dove f(s) frequenza di s nel file Nel nostro caso: (1*0.35+2*0.25+3*0.21+4*0.15+4*0.04)*L= 131 2.24*L<3*L (3*L-2.24*L)/(3*L)=0.76/30.253, quindi abbiamo salvato circa il 25.3% dello spazio 132 Soluzione generale Definizioni formali Quale semplice proprietà assicura assenza di ambiguità nel caso di codifiche a lunghezza variabile? Ogni prefisso (proprio) di una codifica valida è non valido Esempio: i prefissi di 1001 sono la successione vuota , 1, 10 e 100. Se decod(1001) è definito allora decod(), decod(1), decod(10) e decod(100) sono 133 indefiniti Codici e alberi binari Def.: c è prefisso (proprio) di c, prefix(c,c'), se e solo se |c|<|c'| e per ogni i < |c| c(i)=c'(i+|c'|-|c|) Def.: codice a lunghezza variabile non ambiguo rispetto ai prefissi: per ogni c, c' se prefix(c,c') e decod(c') è definito, allora decod(c) è indefinito 134 Definizione intuitiva di albero N.B.: per definizioni più formali vedere il corso di ASD Idea: un codice non ambiguo rispetto ai prefissi si può rappresentare con un albero binario posizionale (al posto di posizionale spesso si usa impropriamente anche il termine ordinato) 135 Un albero è formato da un insieme non vuoto di nodi e un insieme di archi. Ogni arco connette due nodi e ha una direzione. Non possono esistere due archi diversi che vanno da un nodo a un altro, ossia l'insieme degli archi è una relazione 136 binaria tra i nodi dell'albero. Rappresentazione e terminologia Definizione di albero Esempio: l'arco e va n1 a n2. n1 e n2 e è arco uscente da n1 ed entrante in n2 n2 è figlio (child) di n1, n1 parent di n2 Un cammino è una successione non vuota di nodi n1...nk tale che esiste l'arco da ni a ni+1 per ogni i=1..k-1 n1 n2 nk-1 nk 137 I nodi sono in numero finito Esiste un unico nodo detto radice che non ha alcun arco entrante A parte la radice, tutti gli altri nodi hanno un solo arco entrante Non esistono cammini ciclici, ossia del tipo n1, n2,...,n1 Altezza albero: numero archi di un cammino massimo (radice - foglia) 138 Esempio di albero binario posizionale Alberi binari posizionali Tutti i nodi hanno al più 2 archi uscenti e ogni arco può essere destro o sinistro; quindi ogni nodo può avere: 0 archi uscenti (viene detto foglia) 1 arco destro uscente 1 arco sinistro uscente 2 archi uscenti, uno destro e l'altro sinistro radice figlio sinistro foglia 139 figlio destro arco destro arco sinistro foglia foglia 140 Archi etichettati Archi etichettati Seguiamo la seguente convenzione: archi sinistri etichettati con 0, archi destri etichettati con 1 Esempio: radice 0 n1 010 n2 011 A ogni foglia n possiamo associare la configurazione di bit corrispondenti alle etichette degli archi che compongono il cammino dalla radice alla foglia n 1 0 1 n3 10 foglia n3 0 1 foglia n1 foglia n2 141 142 Codici e alberi Codice e alberi Ogni codice (finito, a lunghezza fissa o variabile) non ambiguo rispetto ai prefissi può essere rappresentato da un albero binario posizionale, dove le foglie corrispondono agli elementi codificati. Viceversa, ogni albero binario posizionale rappresenta un codice non ambiguo rispetto ai prefissi dove gli elementi codificati corrispondono alle foglie. Esempio: il codice tale che cod(A)={01}, cod(E)={100}, cod(I)={101}, cod(O)={110}, cod(U)={111} corrisponde al seguente albero 0 1 1 0 1 A 0 143 E 1 I 1 0 O U 144 Codici a espansione Formati multipli predefiniti Utili schemi per rappresentare istruzioni con codici operativi a lunghezza variabile. Esempio: formati multipli predefiniti con cifra di espansione con configurazione di espansione Sono schemi che garantiscono codici non ambigui rispetto ai prefissi, quindi tutti rappresentabili con alberi binari posizionali formato 1 a 4 bit: 00b1b0 (22 config.) formato 2 a 6 bit: 01b3b2b1b0 (24 config.) formato 3 a 9 bit: 10b6...b0 (27 config.) formato 4 a 13 bit: 11b10...b0 (211 config.) 145 146 Formati multipli predefiniti Cifra di espansione Rappresentazione ad albero 0 2 0 1 1 0 n = albero completo di altezza n (2n foglie) 1 4 7 formato 1 formato 2 Esempio: formato 1 a 4 bit: 0b2b1b0 (23 config.) formato 2 a 6 bit: 10b3b2b1b0 (24 config.) formato 3 a 9 bit: 110b5...b0 (26 config.) formato 4 a 13 bit: 111b9...b0 (210 config.) 11 formato 3 147 formato 4 148 Configurazione di espansione Cifra di espansione Rappresentazione ad albero 0 Esempio: formato 1 a 4 bit: b3b2b1b0 1 0 1 3 formato 1 0 1 4 10 formato 3 149 formato 4 Configurazione di espansione Permette la generazione di un codice ottimale (che minimizza il numero di bit necessari per la codifica) basata sull'analisi della frequenza dei simboli 1 0 3 1 0 2 1 0 1 1 0 1 1 0 formato 1 formato 2 1 0 2 1 0 1 formato 3 Idea: l'albero binario posizionale che rappresenta il codice viene generato a partire dalle foglie (approccio bottom-up) 1 0 150 Codifica di Huffman Rappresentazione ad albero 0 (escluso 1..1, 22-1 config.) formato 3 a 9 bit: 111111b2b1b0 (escluso 1..1, 23-1 config.) 4 formato 4 a 13 bit: 1..1b b b b (2 config.) 3 2 1 0 formato 2 6 (escluso 1..1, 24-1 config.) formato 2 a 6 bit: 1111b1b0 151 152 Generazione codice ottimale Generazione codice ottimale Algoritmo di costruzione dell'albero: Esempio f(A)=0.35,f(E)=0.25,f(O)=0.21,f(I)=0.15, I nodi vengono inseriti in una coda di priorità; nodi con frequenza più bassa hanno priorità più alta. f(U)=0.04 Si estraggono due nodi dalla coda (ossia, quelli con le frequenze minori f1 e f2), si crea un nuovo nodo genitore n con frequenza f1+f2, si inserisce n nella coda. L'algoritmo termina quando nella coda rimane un solo nodo (la radice) Fase iniziale: coda di foglie E 0.25 A 0.35 154 I restanti passi: A 0.35 0.4 O 0.21 I 0.15 U 0.04 Generazione codice ottimale Creazione di un nodo non foglia E 0.25 I 0.15 153 Generazione codice ottimale A 0.35 O 0.21 0.19 O 0.21 U 0.04 I 0.15 155 E 0.25 0.19 U 0.04 156 Generazione codice ottimale Generazione codice ottimale Albero finale: 0.4 0.6 E 0.25 A 0.35 O 0.21 1 A 0.35 U 0.04 I 0.15 0.4 0.6 0.19 E 0.25 O 0.21 I 0.15 157 Generazione codice ottimale Codice generato: 0 0 A NOTA BENE: è un albero full, ossia ogni nodo può avere 0 o 2 figli (ma non 1). 1 0 1 E 1 O 0 I 1 U A 00, E 01, O 10, I 110, U 111 Spazio risparmiato rispetto a lunghezza fissa 3 159 (3- (0.81*2+0.19*3))/3=0.27 0.19 U 0.04 158