2. Scopul
● Prezentarea și analiza a unei serii de algoritmi de sortare
● Paralelizarea algoritmilor
● Obținerea de rezultate experimentale ale algoritmilor paraleli
● Construirea de algoritmi paraleli hibrizi
● Obținerea de rezultate experimentale ale algoritmilor hibrizi
3. Motivația
● Fascinația personală pentru algoritmi de sortare
● Dorința de a construi și rula astfel de algoritmi pe arhitecturi
paralele
● Dorința de a construi algoritmi de sortare hibrizi și de a descoperi
dacă aceștia oferă sporuri de performanță
● Metoda de cercetare - predominant experimental
4. Categorii de algoritmi de sortare
Dupa metoda generală de lucru:
● Inserție (insertion sort, shellsort, cyclesort)
● Selecție (selection sort, heapsort)
● Partiționare (quicksort, introsort)
● Interclasare (mergesort, timsort)
Am ales câțiva:
● Quicksort, Mergesort - divide et impera
● Selection sort, Heapsort
5. Quicksort, Mergesort
● Algoritmi recursivi
Împart lista de intrare în sub-liste
T(n)
●
T(n/2) T(n/2)
● Rulează recursiv pe aceste sub-liste
T(n/4) T(n/4) T(n/4) T(n/4)
● n=1 cazul de bază
T ( n/2 k )
● Apelurile => arbore de recurență
T(1) T(1) T(1) T(1) T(1) T(1) T(1) T(1)
● Quicksort și Mergesort: Ο(nlog (n ))
● Quicksort: cazul nefavorabil: Ο(n 2) - arborele de recurență devine
liniar
6. Paralelizarea algoritmilor
● Algoritmii "divide et impera" - pot fi paralelizați cel mai ușor
● Firele de execuție nu trebuie să se sincronizeze
n n
● Nu facem paralelizarea în funcție de nr. de procesoare Ο(
p
log( ))
p
● Paralelizare în funcție de nivelul de recurență
● La fiecare nivel de recurență putem lansa procese separate
● Arborele de procese se va suprapune arborelui de recurență al
algoritmului
7. Paralelizarea algoritmilor
N0
N1
N2
N3
● N0 – nivelul rădăcină, apelul inițial al funcției
● N1 – rezultatul a 21 apeluri ale funcției, fiecare pe câte o sub-listă
● N2 – rezultatul a 2 2 apeluri, fiecare pe câte o sub-listă a nivelului
anterior
● La fiecare nivel putem lansa 2i procese
8. Paralelizarea algoritmilor
● Ne vom limita la N0 - N3, respectiv 1, 2, 4 și 8 procese
● După ce acest nivel e depășit, algoritmul la rula în mod secvențial
mai departe
● Între procese separate - comunicare (IPC) printr-un obiect de tip
coadă
● Obiectul coadă e accesibil de către procesul părinte și cei doi
copii ai săi (local)
● Între apeluri de funcție obișnuite - return
9. Rezultate experimentale - cum am testat
● Listă aleatoare, listă sortată crescător, listă sortată descrescător
● Fiecare algoritm a fost rulat de 10 ori pe fiecare listă de intrare
● Fiecare algoritm a fost rulat pe liste de 10.000 (10k), 100.000
(100k), 1.000.000 (1M) și 5.000.000 (5M) de elemente, nr nat.
● Rulați:
● în mod secvențial, pe 1 core
● în mod paralel 2 cores și 6 cores
● Comparați pentru corectitudine cu implementarea standard
Python (Timsort)
10. Rezultate experimentale – secvențial
● secvențial: Quicksort, Mergesort și Heapsort, 100k elemente
lista aleatoare lista sortata crescator lista sortata descrescator
1400
1200
1000
800
ms
600
400
200
0
quicksort_first quicksort_middle quicksort_avg3 quicksort_minmax mergesort heapsort
● Quicksort_first - depașește limita de recursivitate
11. Rezultate experimentale – paralel
● Am selectat Quicksort_middle și Mergesort
● 2, 4 sau 8 procese pt. fiecare algoritm, 10k elemente, 2 cores
lista aleatoare lista sortata crescator lista sortata descrescator
1200
1000
800
600
ms
400
200
0
quicksort_middle, 2p mergesort, 2p quicksort_middle, 4p mergesort, 4p quicksort_middle, 8p mergesort, 8p
12. Rezultate experimentale – paralel
● 10k elemente, 6 cores
lista aleatoare lista sortata crescator lista sortata descrescator
100
90
80
70
60
50
ms
40
30
20
10
0
quicksort_middle, 2p mergesort, 2p quicksort_middle, 4p mergesort, 4p quicksort_middle, 8p mergesort, 8p
● Diferențele sunt mult mai mici pe 6 cores
● Pe măsură ce lista de intrare devine mai mare diferențele dispar
13. Rezultate experimentale – secvențial vs. paralel
● Eliminăm listele sortate crescător și descrecător. Random, 5M:
secvential 2 cores 6 cores
70000
60000
50000
40000
30000
20000
10000
0
mergesort mergesort, 2p mergesort, 4p mergesort, 8p
ms
quicksort_middle quicksort_middle, 2p quicksort_middle, 4p quicksort_middle, 8p
● Mergesort paralel vs. secvențial: 56404ms vs. 31698ms
● Quicksort paralel - performanțe slabe
14. Construirea algoritmilor hibrizi
● Compuși din doi algoritmi:
● unul de tip divide et impera
● unul secvențial
● Odată ce algoritmul principal trece de un anumit nivel va avea
performanțe slabe - overhead
● De la un anumit nivel vom trece la un algoritm secvențial
● Cel secvențial va avea performanțe mai bune pe liste mici
15. Construirea algoritmilor hibrizi
lista aleatoare
9
8
7
6
5
ms
4
3
2
1
0
quicksort_middle mergesort heapsort selection
● Selection sort va avea performanțe mai bune pe liste de 1000 el.
● După 4000 elemente, performanțele sale se degradează
16. Construirea algoritmilor hibrizi
● Am ales nivelul de recurență 12, 212 =4096
Niveluri de recurență pt Lungimea listei sortate de
fiecare lungime sub-algoritm
13
10k≈2 10k /4096≈2
17
100k≈2 100k /4096≈24
1M≈2
20 1M / 4096≈244
5M≈2
22 5M /4096≈1220
17. Construirea algoritmilor hibrizi
Descrierea completă a algoritmului:
● până la nivelul 1, 2 sau 3 vom lansa procese separate (2, 4
respectiv 8)
● până la nivelul 12 vom rula algoritmul secvențial
● de la nivelul 12 vom rula sub-algoritmul pe liste mici
● dacă lista de intrare e mai mică de 4096, sub-algoritmul nu va
intra în funcțiune => algoritm adaptiv
18. Rezultate experimentale - algoritmi hibrizi
● Quicksort cu Heap și Selection
● Mergesort cu Heap și Selection
secvential 2 cores 6 cores
16000
14000
12000
10000
8000
6000
4000
2000
0
ms
mergesort mergesort P quick_heap H merge_heap H
quicksort quicksort P quick_selection H merge_selection H
● 1M elemente, 2p
19. Concluzii ale experimentelor
● Quicksort - rezultate slabe
● Mergesort - și mai rapid după hibridizare
● Mergesort cu selection sort - cel mai rapid:
● de 1.90 ori mai rapid decât mergesort secvențial în medie,
(2.14 max)
● de 1.10 ori mai rapid decât mergesort paralel simplu în
medie, (1.22 max)
● Varianta cu 4 procese - performanțe constante atât pe 2 cores cât
și pe 6 cores, varianta cu 2 procese dispusă la fluctuații
20. Concluzii și posibilități de îmbunătățire
● Am construit un algoritm paralel hibrid adaptiv
● Odată ce avem acest algoritm putem să-l implementăm pe
arhitecturi cum este CUDA:
● programe generale rulate pe GPU
● procesoare puternic paralele
● un nr. mare de cores (480)
● mai rapid decât CPU pt asemenea task-uri