MODELLISTICA IMPIANTI E SISTEMI 1 A.A. 2007-2008 Docente Davide DiLiegino
PROGETTO FINALE
Enrico Fasani
Matricola 0075672
Soluzione Esercizio 1) Dati del problema Tempo di risposta del sistema : R = 15 s Utenti presenti : N = 10 utenti Grado di utilizzazione della CPU : ρCPU = 75% = 0,75 Domanda di sevizio della CPU : DCPU = 3 s Il modello del sistema è quello chiuso. Dalla Legge dell’ utilizzazione, applicando il flusso forzato, sappiamo che : ρCPU = UCPU = XCPU * SCPU = X * DCPU Da ciò si ricava : X = ρCPU / DCPU Quindi il valore di X è : X = 0,75 / 3 = 0,25 utenti/s Dalla Legge di Little si ha : R+Z=N/X → Z=N/X-R Concludendo, si ottiene : Z = 10 / 0,25 – 15 = 40 – 15 = 25 s
Soluzione Esercizio 2) Dati del problema Tempo di Osservazione : T = 8000 s ndb = (C, CDisk1 , CDisk2, BCPU, BDisk1, BDisk2 ) Numero di job arrivati : A = 1600 Numero di job completati : C = 1600 Numero di accessi a Disk1 : CDisk1 = 32000 Numero di accessi a Disk2 : CDisk2 = 12000 Tempo di occupazione di Disk1 : BDisk1 = 1280 sec Tempo di occupazione di Disk2 : BDisk2 = 3360 sec Tempo di occupazione della CPU : BCPU = 1277 sec
Risposta b1) Parametrizzazione : Numero di completamenti della CPU : CCPU = C + CDisk1 + CDisk2 = 45600 Ricordando la Legge delle Visite, la quale afferma che il numero medio di visite dei vari centri è Vk = Ck / C : VCPU = CCPU / C = 45600 / 1600 = 28,5 VDisk1 = CDisk1 / C = 32000 / 1600 = 20 VDisk2 = CDisk2 / C = 12000 / 1600 = 7,5 I tempi medi di servizio per ogni unità si ricavano dalla relazione Sk = Bk / Ck : SCPU = 1277 / 45600 = 0,028 sec SDisk1 = 1280 / 32000 = 0,004 sec SDisk2 = 3360 / 12000 = 0,28 sec Dalle numero medio di visite e dal tempo medio di servizio, otteniamo la domanda di servizio di ogni unità dalla relazione Dk = Vk * Sk : DCPU = VCPU * SCPU = 28,5 * 0,028 = 0,798 sec DDisk1 = VDisk1 * SDisk1 = 20 * 0,004 = 0,08 sec DDisk2 = VDisk2 * SDisk2 = 7,5 * 0,28 = 2,1 sec I tassi di servizio per ogni centro si ricavano dalla relazione μk = 1 / Sk : μCPU = 1 / SCPU = 35,7 sec-1 μDisk1 = 1 / S Disk1 = 250 sec-1 μ Disk2 = 1 / S Disk2 = 3,57 sec-1 Infine, le probabilità di routing si ricavano dalle visite di ogni unità : pCPU,CPU = 1 / (VDisk1 + VDisk2 + 1) = 1 / VCPU = 0,035 pCPU,Disk1 = VDisk1 / VCPU = 0,702 pCPU,Disk2 = VDisk2 / VCPU = 0,263
Risposta b2) Calcolo della curva asintotica pessimistica ed ottimistica del tempo medio di ciclo nell’ insieme attivo : Numero di Utenti : N = 1,2,3 … , 10 Tempo di Generazione dei Comandi (Think Time) : Z = 25 sec Massimo della Domanda delle unità : Dmax = 2,1 sec Throughput dell’ impianto : N / (N * D + Z) ≤ X(N) ≤ min [1 / Dmax , N / (D + Z)] Tempo di Risposta : max (D, N * Dmax - Z) ≤ R(N) ≤ N * D Domanda Totale di Servizio : D = DCPU + DDisk1 + DDisk2 = 2,978 sec Limite Superiore del throughput : (1 / Dmax) = 0,476 sec-1 N* = D / Dmax = 1,761 jobs
N 1 2 3 4 5 6 7 8 9 10
N 1 2 3 4 5 6 7 8 9 10
D 2,978 2,978 2,978 2,978 2,978 2,978 2,978 2,978 2,978 2,978
Z
Inf [X(N)] 0,0357423690042176 0,0646078304690529 0,0884069075263747 0,1083658430862590 0,1253446979192780 0,1399645423159470 0,1526850761244170 0,1638538423726040 0,1737384656963050 0,1825483753194600
25 25 25 25 25 25 25 25 25 25
N / (ND + Z) 0,0357423690042176 0,0646078304690529 0,0884069075263747 0,1083658430862590 0,1253446979192780 0,1399645423159470 0,1526850761244170 0,1638538423726040 0,1737384656963050 0,1825483753194600
Sup [X(N)] 0,0357423690042176 0,0714847380084352 0,1072271070126530 0,1429694760168700 0,1787118450210880 0,2144542140253060 0,2501965830295230 0,2859389520337410 0,3216813210379580 0,3574236900421760
N/D+Z 0,0357423690042176 0,0714847380084352 0,1072271070126530 0,1429694760168700 0,1787118450210880 0,2144542140253060 0,2501965830295230 0,2859389520337410 0,3216813210379580 0,3574236900421760
(N * Dmax) - Z -22,9 -20,8 -18,7 -16,6 -14,5 -12,4 -10,3 -8,2 -6,1 -4
Dmax 2,1 2,1 2,1 2,1 2,1 2,1 2,1 2,1 2,1 2,1
1 / Dmax 0,47619048 0,47619048 0,47619048 0,47619048 0,47619048 0,47619048 0,47619048 0,47619048 0,47619048 0,47619048
Inf [R(N)] 2,978 2,978 2,978 2,978 2,978 2,978 2,978 2,978 2,978 2,978
Sup [R(N)] 2,978 5,956 8,934 11,912 14,89 17,868 20,846 23,824 26,802 29,78
3) Progetto del simulatore software L’implementazione del simulatore ha seguito i paradigmi della progettazione a oggetti. E’ stata pertanto eseguita una prima fase di analisi del modello, per individuare le entità da tradurre in classi e le loro relazioni. Le classi risultanti sono state raccolte in alcune tipologie, che hanno costituito la base del programma: ogni tipologia è stata tradotta in un package Java contenente le classi strettamente correlate tra loro. Le tipologie individuate per la creazione dell’impianto sono: Code Distribuzioni Entità Esperimento Numeri Casuali Parametri Variabili del Sistema Altre tipologie accessorie ma necessarie per la gestione del programma: Eccezioni Interfacce Varie Nelle figure successive, sono rappresentati gli schemi delle classi, delle loro relazioni di parentela e dell’utilizzo delle interfacce definite: le classi mancanti non sono legate ad altre da tali relazioni.
Figura 1: Schema delle classi Entità / Numeri Casuali / Variabili.
Figura 2: Schema delle classi Code.
Figura 3: Schema delle classi Distribuzioni.
Alcuni requisiti del programma sono stati forniti nel testo del progetto e sono: Rappresentazione del carico tramite simulazione guidata da distribuzioni (simulazione Monte Carlo) Avanzamento per passi fissi Organizzazione a scansione di attività La simulazione guidata dalle distribuzioni, prevede che ogni unità presente nell’impianto generi i propri tempi di servizio attraverso una distribuzione di probabilità prefissata, così come anche i tempi di arrivo degli utenti rispondano a una distribuzione di probabilità stabilita a priori. Ciò si ottiene attraverso il procedimento analitico della trasformazione inversa: una sequenza di numeri casuali, compresi nell’intervallo [0,1), estratti da una popolazione a densità di probabilità esponenziale, viene trasformata attraverso l’inversa della funzione cumulativa F-1 della distribuzione di probabilità, per ottenere il valore desiderato (vedi [1]). Il primo meccanismo da sviluppare è stato, quindi, la generazione di sequenze di numeri casuali uniformi rispondenti alle necessità.
Generatore di numeri casuali Per la generazione di numeri casuali all’interno del programma, sono stati utilizzati due metodi algoritmici: 1. Metodo della Congruenza Lineare 2. Metodo Additivo I metodi sono spiegati in [2]. Dato l’utilizzo di algoritmi per la loro generazione, si parla di numeri pseudo-casuali. Inizialmente, si è implementato il metodo della congruenza lineare per la generazione di una lista di numeri di tipo double nel programma : nonostante l’utilizzo dei parametri ottimizzati come descritto in [2], per problemi di arrotondamento si è riusciti ad ottenere una sequenza di soli 8.109 numeri casuali univoci. La scelta del tipo double è stata dettata dal fatto che questa tipologia di numero decimale, ha una grande tolleranza agli errori di arrotondamento, dato il vasto intervallo numerico coperto (da ± 2-1074 a ± (2-2-52)·21023 ). Dato che il metodo additivo prevede la conoscenza pregressa di k numeri, si è posto k = 8.109 e si è utilizzata la sequenza prodotta dal primo metodo come base per il secondo : questo ha portato alla realizzazione di una sequenza di 681.168 numeri casuali univoci. Cambiando il seme delle sequenze successive si ottengono liste di lunghezza sufficiente per tutti gli esperimenti. Inoltre, per evitare la generazione di eccezioni durante l’esecuzione del programma, ogni lista di numeri casuali generata nel simulatore, ha un meccanismo di controllo che, quando la lista estrae l’ultimo numero, la ricrea utilizzando l’ultimo numero come seme per la sequenza successiva. Un test effettuato è stato quello di svuotare per tre volte una lista di 300.000 numeri, e verificare quanti numeri ripetuti fossero stati generati : il risultato è stato 300 numeri doppi su 1.200.000 totali, con un’incidenza dello 0,00025%, e senza che la sequenza venisse ripetuta. I numeri casuali generati sono distribuiti uniformemente tra 0 e 1. Il package nel quale sono contenute tutte le classi per la generazione dei numeri casuali e delle relative liste è denominato simulatore.numeriCasuali.
Generatori di variabili aleatorie per dispositivi di arrivo e servizio Una volta assicurata la corretta generazione di liste di numeri casuali, si è reso necessario implementare le classi per le distribuzioni di probabilità richieste dal simulatore : esponenziale, iperesponenziale, k-erlangiana e uniforme. Come detto in precedenza, queste distribuzioni sono alla base della simulazione con il metodo Monte Carlo, e sono utilizzate per generare i tempi (di arrivo e di servizio) delle entità presenti nel sistema. Data la difficoltà di esprimere analiticamente le inverse della funzione cumulativa di ogni distribuzione, si sono applicati i metodi di calcolo indiretti di ognuna, come spiegato in [2]. Per testare la correttezza degli algoritmi ottenuti, si è proceduto inizialmente con la creazione della distribuzione esponenziale, per via della sua facilità d’implementazione (vedi anche [1]). Generata una sequenza di 10.000 numeri e trasformata con la trasformazione inversa esponenziale, si è proceduto alla verifica della media e della varianza di tale serie, verificando un minimo scostamento dai valori teorici. Inoltre, è stata graficata, ottenendo un grafico coerente con quelli presentati in [1] e [2]. Per la distribuzione iperesponenziale e k-erlangiana, si è proceduto in maniera analoga, creando una sequenza di 10.000 numeri casuali, e trasformandola attraverso due distribuzioni configurate in modo tale da risultare identiche a una distribuzione esponenziale (per l’iperesponenziale si è posto p=0.5, mentre per la k-erlangiana k=1). Per verificare la bontà della sequenza ottenuta, si è proceduto verificandone media e varianza, come per l’esponenziale, confrontandole con i valori teorici; inoltre si è confrontato il grafico ottenuto dai valori generati, con quello dell’esponenziale: il fatto che risultino identici, conferma la correttezza degli algoritmi. Si è proceduto poi a eseguire un ulteriore test sulle 2 distribuzioni (iperesponenziale e k-erlangiana) utilizzando i parametri richiesti dal progetto (p=0.6 e k=2), verificando anche per queste la correttezza di media, varianza e forma grafica della funzione risultante. I risultati dei test sono mostrati nell’ allegato A. Il package nel quale sono contenute tutte le classi per i generatori e delle relative liste è denominato simulatore.distribuzioni. Per lo sviluppo dei generatori fin qui descritti, si è resa necessaria la creazione delle classi per la gestione delle 3 discipline di code: FIFO, LIFO e RAND. Tali classi sono comprese nel package simulatore.code.
Schema del programma del simulatore Come detto, il simulatore prevede l’organizzazione a scansione di attività, che esamina tutte le attività delle unità funzionali presenti nell’impianto ad ogni avanzamento del clock. Per questo tipo di organizzazione, la scelta dell’intervallo fisso di avanzamento del clock risulta essere fondamentale : in base ai parametri ricavati dall’Esercizio 2, il valore dell’avanzamento è stato stabilito in 0,01 secondi. In considerazione di questo e dell’unica classe di utenti presente nel sistema, si è scelto per il programma lo schema con avanzamento a passi fissi. Nelle figure, sono rappresentati i due requisiti :
Figura 4: Organizzazione del modello a scansione di attività.
Figura 5: Schema con avanzamento a passi fissi.
Il programma fonde entrambi gli schemi, in particolare la classe Run, che rappresenta l’esecuzione di un singolo esperimento, implementa i metodi denominati nell’organizzazione, e al loro interno contiene i blocchi dell’avanzamento a passi fissi.
Nella tabella sottostante, sono riportate le corrispondenze : Attività dell’organizzazione Inizializzatore
- Blocco (1)
clock := clock + Δt
- Blocco (6)
Sorgente
- Punto D - Blocco (2) : Macchina degli Arrivi - Punto C - Blocco (3) - Blocco (4) - Blocco (5) - Blocco (13) - Blocco (14) - Blocco (15)
Fine Simulazione
- Blocco (6) - Blocco (12) - Blocco (11) - Blocco (8) - Blocco (9) - Blocco (10)
Blocchi dello schema
Le attività delle singole unità funzionali (CPU, Disk1 e Disk2) sono implementate seguendo lo schema fornito in [1]. Ogni esperimento ha una sola lista di numeri casuali, alla quale accedono tutti gli oggetti creati al suo interno per ricavare i numeri di cui necessitano. L’unica eccezione a questa regola è rappresentata dalla lista di numeri necessari ad ogni utente per stabilire, nella procedura dell’indicatore di routing, a quale unità accedere successivamente : in questo caso, ogni oggetto di tipo Utente genera una propria lista di numeri da usare internamente per questa funzione. Particolare attenzione è stata posta, durante lo sviluppo, a gestire le eccezioni legate alla memoria heap del processo java : per questo si è implementato il meccanismo di rigenerazione delle liste di numeri casuali ed il metodo di finalizzazione esplicita (non lasciata alla gestione del garbage collector) degli oggetti di tipo Utente. I dati di ogni esperimento vengono salvati in un file di testo, opportunamente formattati per permettere la loro importazione in tabelle Access, in directory univoche e differenziate per ogni esecuzione del programma. La classe di gestione dell’ esperimento si trova nel package simulatore.esperimento .
Esecuzione del Primo Esperimento Per stimare in maniera corretta i risultati della simulazione, occorre che la distribuzione della popolazione osservata di utenti sia stazionaria, cioè che i suoi parametri, quali la media e la varianza, siano costanti nel tempo. Inoltre è necessario che le osservazioni siano indipendenti tra loro, cioè che i tempi riscontrati in una non dipendano dalla precedente e non influenzino la successiva. Questo accade quando il sistema raggiunge la stazionarietà. Per ottenere (con buona approssimazione) queste due condizioni, occorre eliminare quella che viene definita la polarizzazione iniziale o initial bias : chiaramente, all’inizio le code sono vuote ed i primi utenti riscontreranno dei tempi più bassi per eseguire le loro operazioni. Per eliminare tale polarizzazione, è necessario ignorare le prime n osservazioni : per stabilire quante osservazioni escludere dalle statistiche finali, è necessario stabilire delle grandezze significative da osservare ed eseguire un primo esperimento. Raccolti tutti i dati delle grandezze scelte, questi vengono esaminati per stabilire quando cominciano a stabilizzarsi. Il valore trovato, viene scelto come valore iniziale delle osservazioni degli esperimenti effettivi. Per quanto riguarda il simulatore sviluppato, si è stabilito di osservare i tempi di attesa di un utente nelle code delle 3 unità, tempi medi per ciclo. Dai risultati si sono generati dei grafici, sotto riportati, e si è stabilito un valore di osservazioni pari a 1000, dopo il quale i tempi tendono a stabilizzarsi (osservare la linea rossa delle media mobile).
Figura 6: Tempo Medio Attesa CPU
Figura 7: Tempo Medio Attesa Disk1
Figura 8: Tempo Medio Attesa Disk2
Modello dell’ Impianto Il modello funzionale dell’ impianto, è descritto in figura:
Figura 9: Modello Funzionale
Un utente richiede inizialmente una quantità predefinita di risorse a lungo termine (Mcc) : se disponibile, diviene attivo e accede alla coda della CPU; altrimenti viene posto in coda in attesa si liberino risorse sufficienti. La coda delle risorse a lungo termine è limitata a 20 utenti : quelli in eccesso, si perdono. Una volta entrato nell’ insieme attivo, l’ utente dovrà completare una serie di cicli, prima di poterne uscire, liberando le risorse a lungo termine occupate in precedenza. Il numero di cicli è stabilito al momento della generazione dell’ utente, con legge di distribuzione uniforme. Un ciclo comincia accedendo alla CPU, e finisce quando un utente entra in coda alla CPU provenendo dalla CPU stessa. La probabilità di routing, che stabilisce a quale unità l’ utente in uscita dalla CPU debba accedere, è indicata nella soluzione dell’ Esercizio 2.
Esecuzione degli Esperimenti L’ esecuzione di un singolo esperimento prevede una fase iniziale nella quale non vengono memorizzate statistiche riguardo ai tempi e la fase di raccolta dei dati che prosegue fino al raggiungimento del tempo di fine simulazione (stabilito empiricamente a 200.000 sec). Ogni esperimento fa parte di una sessione di esperimenti, nella quale, terminato un esperimento, si comincia i successivo azzerandone le variabili, i contatori ed il clock, e lasciando inalterato lo stato delle code delle unità funzionali dell’ impianto. Questa ultima condizione, ha portato ad un’ attenta gestione dell’ inizializzazione delle variabili contenenti i dati degli utenti presenti nelle code al momento dell’ inizio del nuovo esperimento : tali utenze, infatti, si troverebbero nella situazione di avere un tempo di interarrivo superiore a quello di uscita dall’ impianto. Questa anomalia è gestita aggiornando il tempo di arrivo in modo tale da avere un tempo di residenza positivo. Date le richieste del progetto, sono state necessarie 10 sessioni di esperimenti, una per ogni valore richiesto di N (numero massimo di utente ammessi nell’ insieme attivo contemporaneamente). Il numero di esperimenti effettuati nella sessione è stabilito con legge di distribuzione uniforme.
Raccolta Dati I dati vengono salvati dal simulatore in file di testo formattati: da questi file i dati sono stati poi importati in Access ed esportate in Excel per le elaborazioni statistiche e grafiche. Nei calcoli non vengono tanto considerati gli utenti, quanto i cicli che essi compiono all’ interno del sistema. Le grandezze di output del simulatore utilizzate per i calcoli finali, sono: Dimensione
Unità di Misura
Utente Numero di Cicli Effettuati nell' Insieme Attivo (1) Istante di Uscita dall’ Impianto (2) Istante di Arrivo nell' Insieme Attivo (3) Tempo di Attesa in Coda Disk2 (4)
Secondi Secondi Secondi
Unità a Breve Termine Numero Totale di Accessi (5) Tempo Totale di Servizio (6)
Secondi
Esperimento Tempo Fine Simulazione (7)
Secondi
Sessione di Esperimenti Numero di Esperimenti della Sessione (8)
-
Derivate Tempo Totale di Esperimento = (7) * (8) (9) (10) Tempo di Risposta Insieme Attivo = (2) – (3) (11) Tempo Medio di Risposta per Ciclo Insieme Attivo = (10) / (1) (12) Tempo Medio per Ciclo di Attesa Disco2 = (4) / (1) (13) Numero Totale di Cicli Effettuati = Σ (1)
Secondi Secondi Secondi Secondi -
Soluzione Esercizio 3 e Conclusioni Risposta c1) Come calcolato nell’ Allegato B, il tempo medio di risposta è di 9,10590954 secondi, stimato (con intervallo di confidenza al 95%) tra 9,09802876 e 9,11379032. Il tempo medio di residenza in Disk2, invece, è di 0,279902538659926 secondi, stimato tra 0,279814689169775 e 0,279990388150077.
Risposta c2) Nell’ Allegato C, vengono calcolate tutte le medie e le stime negli intervalli di confidenza, dei tempi richiesti per le sessioni di esperimenti. In tabella vengono riassunti i risultati:
N 1 2 3 4 5 6 7 8 9 10
Esercizio 2 Inferiore Superiore 2,978 2,978 2,978 5,956 2,978 8,934 2,978 11,912 2,978 14,89 2,978 17,868 2,978 20,846 2,978 23,824 2,978 26,802 2,978 29,78
R(N) Teorico da Dati Sperimentali Inferiore Superiore 3,0866710527627 3,0866710527627 3,0866710527627 6,1768682855789 3,0866710527627 9,2532727346390 3,0866710527627 12,3455448317805 3,0866710527627 15,4423754905388 3,0866710527627 18,5403755436007 3,0866710527627 21,6079294049050 3,0866710527627 24,7363408307431 3,0866710527627 27,7909755490848 3,0866710527627 30,8475586480123
Valore Dati Sperimentali R 3,1010977657901 3,7020858305427 5,2483629364243 5,2549110269174 7,1057825776684 7,1070980055606 9,1059095403262 9,1213804640962 11,2129582303416 11,1996149061883
Inoltre, come si può vedere nell’ Allegato D, per ogni sessione, il sistema è stato riparametrato e sono stati ricalcolati gli asintoti ottimistici e pessimistici come nell’ esercizio 2, per poter effettuare dei raffronti tra i vari valori. Qui riportiamo il grafico di confronto del tempo di risposta, rispetto agli asintoti ricavati dai dati dell‘esercizio 2 e da quelli sperimentali:
Figura 10: Tempo Medio di Risposta
Come si può notare, il grafico dei tempi denota dei tempi di risposta che rientrano all’ interno delle previsioni.
Appendice A : Bibliografia [1]: G. Iazeolla, “Impianti, Reti, Sistemi Informatici. Modellistica, valutazione delle prestazioni, progetto con tecniche analitiche e di simulazione”, Franco Angeli, 2006. [2]: G. Iazeolla, “Introduzione alla Simulazione Discreta”, Boringhieri, 1981-