Sunteți pe pagina 1din 37

KU1K

NUME STUDENŢI: Dumitrescu Andrei 341C2


Dumitru Ionuţ 342C2
Marin Silviu 342C2
Descrierea proiectului
• KU1K is a set of tools for 4D,5D and 6D compact
U(1) lattice gauge theory Monte Carlo simulation
using the Skipis-Vantzos algorithm. As the
calculations involved, even for the 4D case, are
consuming, the project is modular so as to run
on the Grid.
Structura proiectului

• Proiectul este alcatuit din mai multe module,


insa un singur modul (modulul “mapper”)
adauga complexitate foarte mare si astfel este
singurul care este paralelizat.
Structura proiectului
• Mapper
• Initializer
• Sweeper
• Binner
• Bin2txt
• Cumulants
• Meaner
• Scripturi Python
Modulul Mapper
• Modulul mapper calculeaza o latice, folosindu-se
de niste parametri si o dimensiune a laticei,
necesara pentru algoritmul Skipis-Vantzos.
• Laticea calculata este folosita ulterior de un
algoritm de simulare Monte Carlo (in cadrul
modulului sweeper), iar dimensiunea acesteia
este foarte mare, fapt ce implica o complexitate
mai mare.
Modulul Initializer

• Modulul realizeaza o configuratie initiala


(configuratie fixa) a laticei pentru prima rulare a
algoritmului de simulare Monte Carlo.
Modulul Sweeper

• Este modulul ce realizeaza implementarea


algoritmului Monte Carlo si rularea simularii in
mai multe iteratii folosindu-se de laticea
obtinuta din modulul mapper si configuratia
fixa obtinuta din modulul initializer.
Modulul Binner

• Acest modul realizeaza o histograma a unui


fisier binar care poate fi utilizata pentru a
analiza datele obtinute de simularea Monte
Carlo. Acest rezultat poate fi analizat cu
instrumente de analiza a datelor cum ar fi
GNUPlot sau Mathematica.
Modulul Bin2txt

• Acest modul parseaza fisierul binar obtinut din


modulul sweeper si creeaza un fisier separat
prin tab-uri ce poate fi usor analizat cu
instrumente de analiza a datelor cum ar fi
GNUPlot sau Mathematica.
Analiza modulului Mapper

• Varianta seriala a modului este realizata exclusiv


in functia main, ceea ce nu ne permite sa ne dam
seama unde este situata zona critica in cadrul
codului.
• Am calculat timpii petrecuti in anumite zone ale
codului si am reusit sa extragem zona cu cea mai
mare complexitate, zona pe care am adaugat-o
intr-o functie.
Analiza modulului Mapper

• La prima vedere o zona


de cod precum cea din
dreapta poate parea ca
avand o complexitate
foarte mare, insa dupa
analiza atenta a codului
sursa aflam ca varabila L
se afla in intervalul L =
{4,5,6}. Astfel, observam
ca nu este eficient sa
paralelizam o astfel de
zona.
Analiza modulului Mapper
• Izoland aceasta bucata
de cod in varianta
seriala intr-o functie
(do_work()) am
descoperit ca aceasta
are cea mai mare
complexitate. Functia
este problematica
deoarece N_LOOPS =
{10240, 31250,
77760}.
Profilarea variantei seriale
• In urma profilarii variantei seriale am confirmat
cele suspectate mai sus.
Profilarea variantei seriale
In urma profilarii si rularii variantei seriale cu toate
cele 3 argumente mentionate si anterior ( D = 5 si L
= {4, 5, 6} ) obtinem urmatorii timpi in functie de
numarul de iteratii:

• 10240 de iteratii -> t = 0.594 s


• 31250 de iteratii -> t = 4.479 s
• 77760 de iteratii -> t = 24.95 s
Implementarea paralelizarii
Vom analiza pe rand cele 3 metode de
paralelizare, urmarind zona paralelizata, timpii
obtinuti, problemele intampinate si daca
paralelizarea este sau nu eficienta in fiecare din
cele 3 cazuri:

• OpenMP
• Pthreads
• MPI
Paralelizarea cu OpenMP
• Dupa implementarea variantei seriale, am decis
sa paralelizam programul cu OpenMP.
Descoperind anterior sursa critica a programului
am decis sa paralelizam bucata respectiva de
cod. Rezultate finale fiind diferite de cele seriale
a trebuie sa identificam sursa problemei. Astfel,
am decis ca o anumita bucata de cod trebuia
executata in ordine de catre thread-uri.
Paralelizarea cu OpenMP
Paralelizarea cu OpenMP
Paralelizarea cu OpenMP
Paralelizarea cu OpenMP
• Tot blocul de cod este integrat intr-o zona
#pragma omp parallel avand grija sa pastram
private variabilele critice. For-ul complex este
cel exterior, ce merge pana la N_LOOPS,
mentionat si anterior, astfel ca am paralelizat
acest for cu #pragma omp for ordered
schedule(dynamic,chunk).
Paralelizarea cu OpenMP
• Chunk-ul este calculat anterior in functie de
numarul de thread-uri date ca argument
programului, iar optiunea ordered este folosita
deoarece exista o sectiune critica in cadrul
algoritmului unde este necesar ca thread-urile sa
execute in ordine. Astfel am extras zona intr-o
functie auxiliara care calculeaza si modifica
valorile din cadrul matricei adjLoops.
Rezultate obtinute cu OpenMP

• Timpii obtinuti (pe


coada ibm-dp.q) dupa
paralelizarea cu
OpenMP in functie de
numar de thread-uri.
Am marit numarul de
thread-uri pana in
punctul in care timpul
incepea sa creasca din
nou.
Rezultate obtinute cu OpenMP
Rezultate obtinute cu OpenMP
Rezultate obtinute cu OpenMP
Probleme paralelizare cu OpenMP

• Principala problema intalnita a fost cea legata de


obtinerea unor rezultate eronate in varianta
paralelizata. Aceste rezultate eronate apareau
deoarece, asa cum am mentionat si ilustrat
anterior, o zona critica trebuie executata in
ordine de catre thread-uri. De asemenea, din
acelasi motiv am obtinut si Segfault.
Paralelizarea cu Pthreads
• Dupa realizarea variantei paralelizate cu
OpenMP am aflat ca exista o sectiune critica in
cadrul hotspot-ului din codul sursa. Aceasta
zona critica a trebuit sa fie protejata in
implementarea anterioara, prin introducerea
#pragma omp ordered, pentru a nu obtine
rezultate nedorite. Astfel in cazul paralelizarii cu
pthreads vom folosi un mutex care va controla
accesul thread-urilor la zona critica.
Paralelizarea cu Pthreads

• Calcularea chunk-ului de parcurs de catre fiecare


thread in parte .
Paralelizarea cu Pthreads

• Am adaugat un mutex care va controla accesul


thread-urilor la zona critica.
Paralelizarea cu Pthreads

• In urma rularii si profilarii putem observa cu


usurinta ca sincronizarea thread-urilor in sub-
zona critica a marit complexitatea pana in
punctul in care programul nu mai este eficient si
obtinem un timp mai slab ca cel de la serial.
Profilarea variantei cu Pthreads
Rezultate obtinute cu Pthreads

• Timpii obtinuti (pe


coada ibm-dp.q) dupa
paralelizarea cu
OpenMP in functie de
numar de thread-uri.
Am marit numarul de
thread-uri pana in
punctul in care timpul
incepea sa creasca din
nou.
Rezultate obtinute cu Pthreads
Probleme paralelizare cu Pthreads

• Asa cum am mentionat si anterior datorita


adaugarii zonei sub-critice implementarea cu
Pthreads nu este una eficienta. Inainte de
adaugarea mutex-ului pentrul controlul
accesului thread-urilor am intampinat si eroarea
Segfault.
Paralelizarea cu MPI
• Avand in vedere paralelizarea cu OpenMP care a
scos un timp mai bun decat implementarea
seriala am decis sa realizam o paralelizare
hibrida MPI/OpenMP.
• La un numar de iteratii atat de mare (N_LOOPS
= {10240, 31250, 77760} ) paralelizarea prin
MPI nu va fi eficienta din cauza overhead-ului pe
care l-ar induce schimbul de mesaje.
Concluzii
• Faptul ca o sub-zona critica din hotspot trebuie
executata in ordine de catre thread-uri adauga o
complexitate nedorita paralelizarilor. In cazul
paralelizarii cu OpenMP nu s-a dovedit a fi prea
mare deoarece timpul scos era mai bun decat cel
serial, insa in cazul cu pthreads s-a dovedit ca
adauga o complexitate prea mare.
Bibliografie
• https://ncit-
cluster.grid.pub.ro/trac/APP2017/wiki/KU1K%
3A
• https://svn-
batch.grid.pub.ro/svn/APP2017/KU1K/

S-ar putea să vă placă și