Paralelní a distribuované výpočty (B4B36PDV)

Podobné dokumenty
Paralelní a distribuované výpočty (B4B36PDV)

Paralelní a distribuované výpočty (B4B36PDV)

Paralelní a distribuované výpočty (B4B36PDV)

Paralení programování pro vícejádrové stroje s použitím OpenMP. B4B36PDV Paralelní a distribuované výpočty

Vlákna a přístup ke sdílené paměti. B4B36PDV Paralelní a distribuované výpočty

Vícevláknové programování na CPU: POSIX vlákna a OpenMP I. Šimeček

4. Úvod do paralelismu, metody paralelizace

Úvod do B4B36PDV. Organizace předmětu a seznámení se s paralelizací. B4B36PDV Paralelní a distribuované výpočty

Paralelní programování

Motivace. Software. Literatura a odkazy

Úvod do OpenMP. Jiří Fürst

Dynamické datové struktury III.

Paralelní grafové algoritmy

Paralelní a distribuované výpočty (B4B36PDV)

A4B33ALG 2010/05 ALG 07. Selection sort (Select sort) Insertion sort (Insert sort) Bubble sort deprecated. Quicksort.

Programování II. Návrh programu I 2018/19

Základní datové struktury

Paralelní architektury se sdílenou pamětí typu NUMA. NUMA architektury

Ústav technické matematiky FS ( Ústav technické matematiky FS ) / 35

Paralelní výpočetní jádro matematického modelu elektrostatického zvlákňování

Obsah. Kapitola 1 Hardware, procesory a vlákna Prohlídka útrob počítače...20 Motivace pro vícejádrové procesory...21

NPRG030 Programování I, 2018/19 1 / :03:07

Martin Lísal. Úvod do MPI

1. Zpracování událostí na pozadí aplikace

Pavel Procházka. 3. prosince 2014

Koncepce (větších) programů. Základy programování 2 Tomáš Kühr

Vyhledávání. doc. Mgr. Jiří Dvorský, Ph.D. Katedra informatiky Fakulta elektrotechniky a informatiky VŠB TU Ostrava. Prezentace ke dni 21.

Rekurze. doc. Mgr. Jiří Dvorský, Ph.D. Katedra informatiky Fakulta elektrotechniky a informatiky VŠB TU Ostrava. Prezentace ke dni 12.

Funkce pokročilé možnosti. Úvod do programování 2 Tomáš Kühr

IB111 Úvod do programování skrze Python

Faculty of Nuclear Sciences and Physical Engineering Czech Technical University in Prague

Základy algoritmizace a programování

Martin Flusser. Faculty of Nuclear Sciences and Physical Engineering Czech Technical University in Prague. October 17, 2016

Vyhledávání. doc. Mgr. Jiří Dvorský, Ph.D. Katedra informatiky Fakulta elektrotechniky a informatiky VŠB TU Ostrava. Prezentace ke dni 12.

Prohledávání do šířky = algoritmus vlny

Úvod do GPGPU J. Sloup, I. Šimeček

Paralelní programování

OPS Paralelní systémy, seznam pojmů, klasifikace

IB108 Sada 1, Příklad 1 Vypracovali: Tomáš Krajča (255676), Martin Milata (256615)

Pokročilé architektury počítačů

Jakub Čermák Microsoft Student Partner

POČÍTAČE A PROGRAMOVÁNÍ

Úvod do jazyka C. Ing. Jan Fikejz (KST, FEI) Fakulta elektrotechniky a informatiky Katedra softwarových technologií

Faculty of Nuclear Sciences and Physical Engineering Czech Technical University in Prague

Algoritmizace Dynamické programování. Jiří Vyskočil, Marko Genyg-Berezovskyj 2010

Rekurzivní algoritmy

Vláknové programování část V

Jazyk C++ II. Šablony a implementace

2) Napište algoritmus pro vložení položky na konec dvousměrného seznamu. 3) Napište algoritmus pro vyhledání položky v binárním stromu.

Paralelní programování

Funkční objekty v C++.

C++ 0x aka C++11. Základním kamenem je třída std::thread

Operační systémy. Cvičení 4: Programování v C pod Unixem

Návrh paralelních algoritmů

Paralelní algoritmy v lineární algebře. Násobení matic

Přehled paralelních architektur. Dělení paralelních architektur Flynnova taxonomie Komunikační modely paralelních architektur

IAJCE Přednáška č. 8. double tprumer = (t1 + t2 + t3 + t4 + t5 + t6 + t7) / 7; Console.Write("\nPrumerna teplota je {0}", tprumer);

Martin Flusser. Faculty of Nuclear Sciences and Physical Engineering Czech Technical University in Prague. December 7, 2016

Obecné výpočty na GPU v jazyce CUDA. Jiří Filipovič

Objektově orientovaná implementace škálovatelných algoritmů pro řešení kontaktních úloh

Náplň. v Jednoduché příklady na práci s poli v C - Vlastnosti třídění - Způsoby (algoritmy) třídění

Static Load Balancing Applied to Time Dependent Mechanical Problems

Paralelní programování

Dynamické programování

Třída PTIME a třída NPTIME. NP-úplnost.

Stromy, haldy, prioritní fronty

RNDr. Michal Kopecký, Ph.D. Department of Software Engineering, Faculty of Mathematics and Physics, Charles University in Prague

Zpětnovazební učení Michaela Walterová Jednoocí slepým,

DobSort. Úvod do programování. DobSort Implementace 1/3. DobSort Implementace 2/3. DobSort - Příklad. DobSort Implementace 3/3

Faculty of Nuclear Sciences and Physical Engineering Czech Technical University in Prague

PARALELNÍ PROCESY A PROGRAMOVÁNÍ

Dopravní plánování a modelování (11 DOPM )

Algoritmizace řazení Bubble Sort

PROGRAMOVÁNÍ V C++ CVIČENÍ

Paralelní architektury se sdílenou pamětí

Kapitola 7: Návrh relačních databází. Nástrahy relačního návrhu. Příklad. Rozklad (dekompozice)

Test prvočíselnosti. Úkol: otestovat dané číslo N, zda je prvočíslem

12. Globální metody MI-PAA

Paralelní programování

Transformace digitalizovaného obrazu

Obecná informatika. Matematicko-fyzikální fakulta Univerzity Karlovy v Praze. Podzim 2012

Programování bez vláken. OpenMP

STROMOVE ALGORITMY Prohledavani do sirky (level-order) Po vodorovnejch carach fronta

Paralelní dotazy v PostgreSQL 9.6 (a 10.0)

Základní datové struktury III: Stromy, haldy

OPTIMALIZACE. (přehled metod)

VYBRANÉ PARTIE Z NUMERICKÉ MATEMATIKY

VÝUKOVÝ MATERIÁL. 3. ročník učebního oboru Elektrikář Přílohy. bez příloh. Identifikační údaje školy

Pole a Funkce. Úvod do programování 1 Tomáš Kühr

Procesy a vlákna - synchronizace

6 Příkazy řízení toku

Vector datový kontejner v C++.

Stromy. Karel Richta a kol. Katedra počítačů Fakulta elektrotechnická České vysoké učení technické v Praze Karel Richta a kol.

Základní operace. Prefix sum. Segmentovaný prefix-sum

for (i = 0, j = 5; i < 10; i++) { // tělo cyklu }

Polymorfismus. Časová náročnost lekce: 3 hodiny Datum ukončení a splnění lekce: 30.března

9. lekce Úvod do jazyka C 4. část Funkce, rekurze Editace, kompilace, spuštění Miroslav Jílek

Dynamicky vázané metody. Pozdní vazba, virtuální metody

Hledání k-tého nejmenšího prvku

Struktura programu v době běhu

Transkript:

Paralelní a distribuované výpočty (B4B36PDV) Branislav Bošanský, Michal Jakob bosansky@fel.cvut.cz Artificial Intelligence Center Department of Computer Science Faculty of Electrical Engineering Czech Technical University in Prague

Dnešní přednáška Motivace

Dnešní přednáška Techniky paralelizace Chci paralelizovat algoritmus XY Jak na to?

Dnešní přednáška Postup Jak na to?

Paralelní programování Co chceme dosáhnout Potřebujeme se rozhodnout jak budeme úlohu dekomponovat, jak budeme úkoly rozdělovat a jakým způsobem zabezpečit celkovou orchestraci Klíčové cíle Vybalancování aby každé vlákno vykonávalo (přibližně) stejnou práci Minimalizace komunikace aby vlákna na sebe nemusely čekat Minimalizace duplicitní/zbytečné práce aby vlákna nepočítali něco, co by se nepočítalo bez paralelizace

Paralelní programování Náhled Problém

Paralelní programování Náhled Problém Dekompozice

Paralelní programování Náhled Problém Dekompozice Rozdělení vláknům

Paralelní programování Náhled Problém Dekompozice Rozdělení vláknům Orchestrace Exekuce

Paralelní programování Balancování Ideálně chceme, aby všechna vlákna/jádra pracovaly a skončily současně 14 Čas výpočtu (s) pro jednotlivé vlákna/procesory 12 10 8 6 4 2 0 P1 P2 P3 P4

Paralelní programování Balancování Ideálně chceme, aby všechna vlákna/jádra pracovaly a skončily současně Čas výpočtu (s) pro jednotlivé vlákna/procesory 14 12 10 8 6 Pokud 1 procesor pracuje o 20% déle, celý program pracuje o 20% déle Vzpomeňte si na Amdhalův zákon 4 2 0 P1 P2 P3 P4

Rozdělení práce Statické rozdělení Fixní a statické rozdělení úkolů pro jednotlivá vlákna Ne nutně v době kompilace Jednou přidělíme vláknům úkoly a toto přidělení je neměnné Kdy nám statické rozdělení pomůže? Všechny úkoly trvají (přibližně) stejně dlouho Každý úkol může trvat různě dlouho, ale víme předem očekávanou dobu trvání Čas výpočtu (s) pro jednotlivé vlákna/procesory 30 20 10 0 P1 P2 P3 P4

Rozdělení práce Dynamické rozdělení Program přiděluje úkoly dynamicky na základě aktuálního vytížení jednotlivých vláken

Rozdělení práce Dynamické rozdělení Program přiděluje úkoly dynamicky na základě aktuálního vytížení jednotlivých vláken Threadpool a fronta úkolů Fronta úkolů Vlákna berou úkoly z fronty. V1 V2 V3 V4

Rozdělení práce Dynamické rozdělení Jak to bude vypadat z pohledu jednoho vlákna? Threadpool a fronta úkolů Čas výpočtu Úkol 1 Přidělování nového úkolu. Není v sériové variantě. A je to exekuce v kritické sekci, která zpomaluje výpočet

Rozdělení práce Dynamické rozdělení Jak to bude vypadat z pohledu jednoho vlákna? Threadpool a fronta úkolů Čas výpočtu Více malých úkolů znamená dobré vybalancování mezi vlákna. Úkol 1 Přidělování nového úkolu. Není v sériové variantě. A je to exekuce v kritické sekci, která zpomaluje výpočet Více malých úkolů znamená více synchronizace a zpomalení.

Rozdělení práce Dynamické rozdělení Můžeme měnit granularitu dekompozice Čas výpočtu Zmenšení počtu úkolů sníží zpomalení kvůli synchronizaci Úkol 1 Úkol 2 Ale můžeme mít problém s vybalancováním.

Rozdělení práce Dynamické rozdělení Jak zvolit správnou velikost úkolu? Neexistuje univerzální odpověď závisí na problému/hw (#CPU) atd. Pokud lze (máme odhad), můžeme přiřazovat dlouhé úkoly nejdřív a pak krátké úkoly

Rozdělení práce Dynamické rozdělení problémy Kde je kritická sekce? Fronta úkolů Všechna vlákna přistupují k jedné společné frontě. Co kdyby mělo každé vlákno vlastní frontu? V1 V2 V3 V4

Rozdělení práce Dynamické rozdělení vlastní fronty Můžeme vytvořit vlastní frontu pro každé vlákno Vlákno vkládá a vybírá úkoly z vlastní fronty V1 V2 V3 V4 Jak zabezpečíme vybalancování?

Rozdělení práce Dynamické rozdělení vlastní fronty Jak zabezpečíme vybalancování? Když má vlákno prázdnou frontu, může ukradnout úkoly z jiné fronty. V1 V2 V3 V4

Rozdělení práce Dynamické rozdělení závislosti Ne vždy je možné pustit libovolný úkol (např. pro spuštění úkolu X musíme znát aktuální hodnotu proměnné Y) Úkol bude zpracovaný vláknem/procesorem pouze v případě, že všechny závislosti jsou splněny V OpenMP např. pomocí #pragma omp tasks depend([in/out/inout]:variables)

Rozdělení práce Dynamické rozdělení závislosti v OpenMP int main(int argc, char* argv[]) { int x = 0; #pragma omp parallel num_threads(thread_count) shared(x) { #pragma omp single { #pragma omp task depend(out:x) { std::this_thread::sleep_for(std::chrono::milliseconds(10)); x++; std::cout << "1: x " << x << "\n"; #pragma omp task depend(in:x) { x *= 3; std::cout << "2: x " << x << "\n"; std::cout << "final: x " << x << "\n"; Když definujeme in závislost, vytvoří se závislosti, vytvoří se závislost úkolu na již generovaných úkolech, které mají pro danou proměnnou nastavenou dependenci out případně inout. return 0;

Rozdělení práce Hybridní přístupy Rozdělení nemusí být pouze statické nebo dynamické V podstatě je možné zvolit libovolný mezistupeň mezi dvěma extrémy Rozdělím úkoly Sbírám statistiky o délce zpracování Přerozdělím úkoly a opakuji

Vzorce paralelizace Datový paralelismus SIMD přístup Rozdělím data a rovnou spustím zpracování pro jednotlivá vlákna Fork-join Jedno vlákno zpracovává část úkolu Identifikuje možné podúkoly a spustí nové vlákna/úkoly

Rozděluj a panuj Quick Sort Základní třídící algoritmus void qs(std::vector<int>& vector_to_sort, int from, int to) { if (to - from <= base_size) { std::sort(vector_to_sort.begin() + from, vector_to_sort.begin() + to); return; Jak budeme paralelizovat? //rozdeleni dle pivota (vector_to_sort[from]) int part2_start = partition(vector_to_sort,from,to,vector_to_sort[from]); if (part2_start - from > 1) { qs(vector_to_sort, from, part2_start); if (to - part2_start > 1) { qs(vector_to_sort, part2_start, to);

Rozděluj a panuj Quick Sort void qs(std::vector<int>& vector_to_sort, int from, int to) { if (to - from <= base_size) { std::sort(vector_to_sort.begin() + from, vector_to_sort.begin() + to); return; Můžeme asynchronně volat rekurzivní úkoly //rozdeleni dle pivota (vector_to_sort[from]) int part2_start = partition(vector_to_sort,from,to,vector_to_sort[from]); if (part2_start - from > 1) { #pragma omp task shared(vector_to_sort) firstprivate(from,part2_start) { qs(vector_to_sort, from, part2_start); if (to - part2_start > 1) { qs(vector_to_sort, part2_start, to);

Rozděluj a panuj Quick Sort Omezíme minimální velikost, aby nedocházelo k false-sharingu Můžeme asynchronně volat rekurzivní úkoly void qs(std::vector<int>& vector_to_sort, int from, int to) { if (to - from <= base_size) { std::sort(vector_to_sort.begin() + from, vector_to_sort.begin() + to); return; //rozdeleni dle pivota (vector_to_sort[from]) int part2_start = partition(vector_to_sort,from,to,vector_to_sort[from]); if (part2_start - from > 1) { #pragma omp task shared(vector_to_sort) firstprivate(from,part2_start) { qs(vector_to_sort, from, part2_start); if (to - part2_start > 1) { qs(vector_to_sort, part2_start, to);

Rozděluj a panuj Quick Sort void qs(std::vector<int>& vector_to_sort, int from, int to) { if (to - from <= base_size) { std::sort(vector_to_sort.begin() + from, vector_to_sort.begin() + to); return; //rozdeleni dle pivota (vector_to_sort[from]) int part2_start = partition(vector_to_sort,from,to,vector_to_sort[from]); if (part2_start - from > 1) { #pragma omp task shared(vector_to_sort) firstprivate(from,part2_start) { qs(vector_to_sort, from, part2_start); if (to - part2_start > 1) { qs(vector_to_sort, part2_start, to); fork Right part join qs() Left part

Dekompozice se závislostmi paralelizace QuickSortu byla snadná vzhledem k žádné závislosti mezi úkoly Co když jsou úkoly závislé? Problém: Chceme iterativně počítat průměr pro každé pole mřížky A i, j = 0.2 (A i 1, j + A i, j 1 + A i, j + A i + 1, j + A i, j + 1 ) Každou iteraci chceme projít celou matici z horního levého rohu Jaké jsou zde závislosti? Obrázky převzaty z kurzu CMU 15-418/618 na CMU.edu

Dekompozice se závislostmi paralelizace QuickSortu byla snadná vzhledem k žádné závislosti mezi úkoly Co když jsou úkoly závislé? Problém: Chceme iterativně počítat průměr pro každé pole mřížky A i, j = 0.2 (A i 1, j + A i, j 1 + A i, j + A i + 1, j + A i, j + 1 ) Každou iteraci chceme projít celou matici z horního levého rohu Jaké jsou zde závislosti? Obrázky převzaty z kurzu CMU 15-418/618 na CMU.edu

Dekompozice se závislostmi Jakým způsobem můžeme tento problém paralelizovat? Zkusíme nalézt nezávislé úkoly Které uzly lze aktualizovat paralelně? Obrázky převzaty z kurzu CMU 15-418/618 na CMU.edu

Dekompozice se závislostmi Jakým způsobem můžeme tento problém paralelizovat? Zkusíme nalézt nezávislé úkoly Které uzly lze aktualizovat paralelně? Uzly na diagonále jsou nezávislé (mohou přistupovat ke stejné proměnné, ale pouze pro čtení). Problematické rozdělení na vlákna/procesory. Obrázky převzaty z kurzu CMU 15-418/618 na CMU.edu

Dekompozice se závislostmi Existuje lepší způsob? Pro konvergenci nemusíme nutně postupovat sekvenčně z jednoho rohu uzly rozdělíme do dvou skupin a aktualizujeme nejdřív jednu, pak druhou Jednoduchá paralelizace a rozdělení úkolu vláknům. Musíme vědět, že si to můžeme dovolit (znalost problému/domény). Obrázky převzaty z kurzu CMU 15-418/618 na CMU.edu

Dekompozice se závislostmi Existuje lepší způsob? Jak můžeme rozdělit na úkoly pro vlákna/procesory? Obrázky převzaty z kurzu CMU 15-418/618 na CMU.edu

Dekompozice se závislostmi Který je lepší? Které části jsou privátní a které sdílené? Obrázky převzaty z kurzu CMU 15-418/618 na CMU.edu

Hledání prvočísel Eratostenovo síto Problém: Chceme zjistit počet prvočísel mezi 0 a X (např. 10 9 ) Jaký je sériový algoritmus?

Hledání prvočísel Eratostenovo síto Problém: Chceme zjistit počet prvočísel mezi 0 a X (např. 10 9 ) Jaký je sériový algoritmus? long result = 0; for (int i = 2; i < MAXSQRT; i++) { if (primes[i] == 1) { for (int j = i * i; j < MAXNUMBER; j += i) { primes[j] = 0; for (int i = 0; i<maxnumber; i++) result += primes[i]; return result; Jak na to?

Hledání prvočísel Eratostenovo síto Zkusíme paralelizovat hlavní for cyklus Můžeme paralelizovat druhý for cyklus pro součet long result = 0; #pragma omp parallel num_threads(thread_count) { #pragma omp for schedule(static) for (int i = 2; i < MAXSQRT; i++) { if (primes[i] == 1) { for (int j = i * i; j < MAXNUMBER; j += i) { primes[j] = 0; #pragma omp parallel for reduction(+:result) for (int i = 0; i<maxnumber; i++) result += primes[i]; return result; Jak nám to bude fungovat?

Hledání prvočísel Eratostenovo síto long result = 0; #pragma omp parallel num_threads(thread_count) { #pragma omp for schedule(static) for (int i = 2; i < MAXSQRT; i++) { if (primes[i] == 1) { for (int j = i * i; j < MAXNUMBER; j += i) { primes[j] = 0; #pragma omp parallel for reduction(+:result) for (int i = 0; i<maxnumber; i++) result += primes[i]; return result; Pro X=10 9 Sériová varianta První paralelizace (4 vlákna) 11.7188 s 13.0681 s

Hledání prvočísel Eratostenovo síto Co se stane když paralelizujeme hlavní cyklus? Např. vlákno 0 bude zpracovávat iteraci i=2, vlákno 2 bude zpracovávat iteraci i=4 Vlákno 2 dělá úplně zbytečnou práci informace o tom, že číslo 4 není prvočíslo se k němu nemusí dostat včas Jaká je závislost mezi úkoly? i=2 i=4 i=3 i=6 i=5 Na to abychom identifikovaly správné pořadí musíme vyřešit vlastní problém

Hledání prvočísel Eratostenovo síto Co se stane když paralelizujeme hlavní cyklus? Např. vlákno 0 bude zpracovávat iteraci i=2, vlákno 2 bude zpracovávat iteraci i=4 Vlákno 2 dělá úplně zbytečnou práci informace o tom, že číslo 4 není prvočíslo se k němu nemusí dostat včas Jaká je závislost mezi úkoly? i=2 i=4 i=3 i=6 i=5 Na to abychom identifikovaly správné pořadí musíme vyřešit vlastní problém

Hledání prvočísel Eratostenovo síto Co se stane když paralelizujeme hlavní cyklus? Např. vlákno 0 bude zpracovávat iteraci i=2, vlákno 2 bude zpracovávat iteraci i=4 Vlákno 2 dělá úplně zbytečnou práci informace o tom, že číslo 4 není prvočíslo se k němu nemusí dostat včas Jaká je závislost mezi úkoly? i=2 i=4 i=3 i=6 i=5 Na to abychom identifikovaly správné pořadí musíme vyřešit vlastní problém

Hledání prvočísel Eratostenovo síto Jak můžeme snížit závislost? Každé vlákno může kontrolovat pouze podinterval čísel 101 102 103 104 105 106 107 108 V1 V2 Úkol pro vlákno: označit čísla, které nejsou prvočísly v daném podintervalu

Hledání prvočísel Eratostenovo síto long sieve() { int step = MAXNUMBER/thread_count/500; long result = 0; #pragma omp parallel num_threads(thread_count) reduction(+:result) { #pragma omp for schedule(static) for (int i = 2; i < MAXNUMBER; i += step) { int from = i; int to = (i + step < MAXNUMBER)? i + step : MAXNUMBER; for (int i = 2; i < MAXSQRT; i++) { if (primes[i] == 1) { int start = std::max((from % i == 0)? from : ((from/i)*i)+i, i*i); for (int j = start; j < to; j += i) { primes[j] = 0; for (int i = from; i < to; i++) result += primes[i]; return result;

Hledání prvočísel Eratostenovo síto long sieve() { int step = MAXNUMBER/thread_count/500; long result = 0; #pragma omp parallel num_threads(thread_count) reduction(+:result) { #pragma omp for schedule(static) for (int i = 2; i < MAXNUMBER; i += step) { int from = i; int to = (i + step < MAXNUMBER)? i + step : MAXNUMBER; for (int i = 2; i < MAXSQRT; i++) { if (primes[i] == 1) { int start = std::max((from % i == 0)? from : ((from/i)*i)+i, i*i); for (int j = start; j < to; j += i) { primes[j] = 0; for (int i = from; i < to; i++) result += primes[i]; return result; Pro X=10 9 1 vlákno paralelizace (4 vlákna) 3.99 s 1.74 s

Hlasování https://goo.gl/a6bemb