• Non ci sono risultati.

Implementazione del Monte Carlo Sequenziale Parallelo

5. Parallelizzazione del metodo Monte Carlo Sequenziale

5.1 Il calcolo parallelo

5.1.2 Implementazione del Monte Carlo Sequenziale Parallelo

Il cuore con il quale è implementato il simulatore è definito da un costrutto di tipo “For Loop”, ne deriva quindi che il processo, nel suo totale, si presta a essere parallelizzato, salvo alcune precisazioni. Questo processo può essere suddiviso in tre parti principali (esclusi i processi di pre e post processing), composti da:

i. inizializzazione: la singola iterazione preleva i dati previsionali della simulazione ed

aggiorna, da essi, i propri dati operativi;

ii. nucleo: parte principale del simulatore, nel quale i soli dati utilizzati sono quelli opera-

tivi;

iii. aggiornamento: effettuata la singola iterazione i dati operativi aggiornano i valori medi

della simulazione e vengono salvati, se ritenuti interessanti, al fine di successive analisi di post processing;

Da tale suddivisione emerge subito una marcata indipendenza dei singoli processi. Da ciò consegue la possibilità di poterli parallelizzare, tranne il fatto di dover utilizzare una barriera di tipo due nel punto iii, in altre parole quando sono aggiornati i dati medi di simulazione. Questa suddivisione è riportata in forma esplicita nella Figura 5-5.

Figura 5-5 Divisione strutturale del ciclo Monte Carlo Sequenziale

Un’altra importante suddivisione è descritta nella Figura 5-6. In questa rappresentazione possono essere distinti i due spazi funzionali caratterizzanti la modellazione dell’algoritmo della simulazione, in altre parole:

i. Spazio della memoria: in tale porzione di memoria sono contenute tutte le variabili

riguardanti i dati previsionali, operativi e di output. Lo spazio può essere suddiviso in quattro parti distinte:

a. Dati strutturali: sono rappresentati da tutte quelle variabili che descrivono il

sistema elettrico. Tale insieme di dati è scritto nella fase di pre-processing dal

Master Thread. Dopo tale definizione, queste variabili rimangono in sola let-

tura per tutti gli Slave thread; un esempio di dati strutturali sono il numero e le caratteristiche dei singoli generatori;

b. Variabili previsionali: come per i dati strutturali, questo insieme di dati è

creato dal Master Thread in fase di pre-processing, dopodiché, tale porzione di memoria diventa di sola lettura per tutti gli Slave thread. Un esempio di va- riabile previsionale è lo Unit Commitment ed il Dispacciamento di un gruppo di generazione;

c. Output: per tale porzione di memoria, contrariamente da quelle precedenti, le

informazioni sono registrate dai singoli Slave thread durante tutto il processo di simulazione. Infatti, essa è l’unica porzione di memoria globale abilitata sia in lettura che in scrittura. Un esempio di variabile di output è il valor medio

Monte Carlo - Inizio

Monte Carlo - Fine g=ge? g=gs

q=qs Setup del giorno

q=qe? Estrazione stato dei componenti Estrazione Errore carico Dispacciamento II a=q+1 a=qe? Dispacciamento III a= a+ 1 No Si Si No q = q + 1 Aggiornamento Indici simulazione g = g + 1 Si No

Copia delle variabili previsionali in quelle operative di simulazione Kernel della simulazione Monte Carlo Sequenziale che utilizza le variabili operative Aggiornamento delle variabili medie con quelle operative di simulazione

g=ge? Monte Carlo - Inizio

g=gs

Monte Carlo - Fine Si No g = g + 1

Simulazione Monte Carlo Sequenziale Copia delle variabili private del singolo scenario

da crare

La singola simulazione "pesa" poiché i suoi risultati aggiornano i valori medi (e salvati se rispettano

nodale dell’energia non fornita. In generale ogni andamento medio è aggior- nato con la seguente equazione:

( )1 1 k k m m i k i i k+ = + 5-8

dove im è il valor medio della variabile i (all’iterazione k-esima);

d. Dati operativi: ogni singolo Slave thread ha riservata una porzione di memo-

ria a lui dedicata, dove solo esso può eseguire operazioni di scrittura e lettura, mentre per gli altri Slave thread tale porzione di memoria risulta inaccessibi- le. Un esempio di dato operativo è il valore del carico al netto delle estrazioni stocastiche;

ii. Spazio dei processi: nello spazio dei processi risiedono tutte le funzioni necessarie ad

effettuare la simulazione. Ogni singolo processo può attingere a tutte le funzioni (e le loro derivate) in modo coerente all’algoritmo di simulazione. E’ importante ricordare che ogni funzione, che è a comune con tutti gli Slave thread, deve essere concepita sot- to lo stretto rispetto del concetto di thread Safe: ciò afferma che una funzione chiamata simultaneamente da due Slave thread dovrà creare di sé due istanze simultanee e indi- pendenti, al fine di evitare incoerenze logiche che distruggerebbero tutto il processo parallelo. Per esempio, se due processi chiamano nello stesso istante temporale le fun- zioni di generazione delle liste di merito, le due istanze di funzione che verranno generate, con i relativi output, dovranno essere indipendenti fra loro, ed accessibili so- lo ai singoli Slave thread che le hanno generate. Tale aspetto risulta di facile comprensione, ma un suo sviluppo pratico richiede un arduo sforzo intellettivo e prati- co. Come ultima nota è importante che un solo processo alla volta aggiorni le variabili di output (com’è possibile vedere nella parte in basso a destra della figura sottostante) per evitare problemi di “race condition”.

Figura 5-6 Suddivisione della memoria

Per estendere l’implementazione del codice seriale al codice parallelo è stato utilizzato il modello di programmazione a memoria condivisa OpenMP (Open Specifications for Multi

Dati Strutturali

(Globali)

Variabili previsionali

(Globali)

Output andamenti medi e dettagliati (Globali) Dati Operativi 1 (Privati) Dati Operativi N (Privati)

Dati Operativi i-esimi

(Privati)

Spazio della memoria Spazio dei processi

Update

Processo 1 Avvio Kernel Verifica

Processo N Avvio Kernel Verifica

Processing), il quale amplia la capacità dei linguaggi di programmazione seriali. Tale OpenMP

nasce per soddisfare i bisogni del calcolo scientifico, che si caratterizzano per il gran numero di calcoli ripetuti. Allo stato attuale lo standard OpenMP è supportato dai più grandi produttori di hardware come IBM, AMD, HP, Intel e SUN, e software come Unix, Linux, Windows e Mac OS: questa elevata compatibilità consente di sviluppare un software con un’elevata interopera- bilità fra i vari sistemi. Il modello concettuale di OpenMP prevede un’esecuzione alternata seriale e parallela, detta “fork/joint” (come anche descritto in precedenza); è ovvio che OpenMP fornisce solo gli strumenti per coordinare i threads, ma è compito del programmatore eseguire la corretta parallelizzazione. Tale estensione si presenta come:

i. direttive al compilatore: pensate come commenti nei vari linguaggi supportati, per pre-

servare il codice seriale e i compilatori non compatibili con l’OpenMP;

ii. libreria di istruzioni: rende il codice dipendente da OpenMP (è necessario includere

l’elenco dei prototipi); le chiamate a tali librerie permettono di determinare ed alterare il numero dei thread;

iii. variabili di ambiente: è possibile definire le variabili comuni a tutti i thread o private

ad ogni singolo thread (definizione funzionale delle singole porzioni di memoria). In conclusione, grazie a tale libreria, è possibile gestire tutta la memoria di sistema secondo le esigenze dettate dall’algoritmo originale della simulazione, ovvero secondo il metodo Monte- carlo Sequenziale.

Documenti correlati