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

Podobné dokumenty
Cvičení předmětu MI-PAR P. Tvrdík, I. Šimeček, M. Šoch

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

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

Paralelní architektury se sdílenou pamětí

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

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

Paralelní architektury se sdílenou pamětí

Úvod do OpenMP. Jiří Fürst

Pokročilé architektury počítačů

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

Cvičení MI-PAP I. Šimeček, M. Skrbek, J. Trdlička

Paralelní programování

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

OpenMP (Open Specification for Multi Processing)

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

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

Procesy a vlákna (Processes and Threads)

Architektury VLIW M. Skrbek a I. Šimeček

Přednáška. Správa paměti II. Katedra počítačových systémů FIT, České vysoké učení technické v Praze Jan Trdlička, 2012

Více o konstruktorech a destruktorech

Uklízení odpadků a analýza úniku

Struktura programu v době běhu

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

Paralelní programování

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

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

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

Programování bez vláken. OpenMP

ZOS 9. cvičení, ukázky kódu. Pavel Bžoch

Pointery II. Jan Hnilica Počítačové modelování 17

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

Přednáška. Vstup/Výstup. Katedra počítačových systémů FIT, České vysoké učení technické v Praze Jan Trdlička, 2012

Pavel Procházka. 3. prosince 2014

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

Procesy a vlákna - synchronizace

Operační systémy. Jednoduché stránkování. Virtuální paměť. Příklad: jednoduché stránkování. Virtuální paměť se stránkování. Memory Management Unit

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

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

ČÁST 1. Základy 32bitového programování ve Windows

Knihovny pro CUDA J. Sloup a I. Šimeček

CUDA J. Sloup a I. Šimeček

Funkce, intuitivní chápání složitosti

Paralelní dotazy v PostgreSQL 9.6 (a 10.0)

Vlákno (anglicky: thread) v informatice označuje vlákno výpočtu neboli samostatný výpočetní tok, tedy posloupnost po sobě jdoucích operací.

Mělká a hluboká kopie

Řada programovacích jazyků nabízí prostředky pro řešení meziprocesové komunikace jako je synchronizace a řízení přístupu do kritické sekce.

Algoritmizace a programování

IRAE 07/08 Přednáška č. 2. atr1 atr2. atr1 atr2 -33

Programování v jazyce JavaScript

Pole stručný úvod do začátku, podrobně později - zatím statická pole (ne dynamicky) - číslují se od 0

Vlákno odlehčený proces kód vlákna, zásobník privátní ostatní sdíleno s dalšími vlákny téhož procesu

IRAE 07/08 Přednáška č. 1

4. Úvod do paralelismu, metody paralelizace

Paralelní programování

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

Programování v C++ 3, 3. cvičení

Principy operačních systémů. Lekce 5: Multiprogramming a multitasking, vlákna

Jazyk C++, některá rozšíření oproti C

2.1 Podmínka typu case Cykly Cyklus s podmínkou na začátku Cyklus s podmínkou na konci... 5

Programování v C++ 2, 4. cvičení

Programování v jazyce JavaScript

Správné vytvoření a otevření textového souboru pro čtení a zápis představuje

Programování v jazyce JavaScript

Management procesu I Mgr. Josef Horálek

Úvod do programování - Java. Cvičení č.4

Čtvrtek 8. prosince. Pascal - opakování základů. Struktura programu:

Optimalizace pomocí icc/gcc - vektorizace

přetížení operátorů (o)

IB109 Návrh a implementace paralelních systémů. Organizace kurzu a úvod. RNDr. Jiří Barnat, Ph.D.

Programování v jazyce C a C++

1. Programování proti rozhraní

Dynamické programování

Maturitní otázky z předmětu PROGRAMOVÁNÍ

Programování v jazyce JavaScript

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

Objektové programování

7.6 Další diagramy UML

- dělají se také pomocí #define - podobné (použitím) funkcím - předpřipravená jsou např. v ctype.h. - jak na vlastní makro:

4. Rekurze. BI-EP1 Efektivní programování Martin Kačer

Rekurzivní algoritmy

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

09. Memory management. ZOS 2006, L.Pešička

7.6 Další diagramy UML

Předmluva k aktuálnímu vydání Úvod k prvnímu vydání z roku Typografické a syntaktické konvence... 20

PREPROCESOR POKRAČOVÁNÍ

MATURITNÍ OTÁZKY ELEKTROTECHNIKA - POČÍTAČOVÉ SYSTÉMY 2003/2004 PROGRAMOVÉ VYBAVENÍ POČÍTAČŮ

Algoritmizace a programování

Datové struktury 2: Rozptylovací tabulky

Pokročilé architektury počítačů

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

Principy operačních systémů. Lekce 6: Synchronizace procesů

Operační systémy. Cvičení 5: Volání jádra, procesy, vlákna.

Jakub Čermák Microsoft Student Partner

11. Přehled prog. jazyků

Pascal. Katedra aplikované kybernetiky. Ing. Miroslav Vavroušek. Verze 7

Z. Kotala, P. Toman: Java ( Obsah )

Sdílení dat mezi podprogramy

konstruktory a destruktory (o)

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

Přednáška 1. Katedra počítačových systémů FIT, České vysoké učení technické v Praze Jan Trdlička, 2012

Transkript:

Vícevláknové programování na CPU: POSIX vlákna a OpenMP I. Šimeček xsimecek@fit.cvut.cz Katedra počítačových systémů FIT České vysoké učení technické v Praze Ivan Šimeček, 2011 MI-PRC, LS2010/11, Predn.2 Příprava studijního programu Informatika je podporována projektem financovaným z Evropského sociálního fondu a rozpočtu hlavního města Prahy. Praha & EU: Investujeme do vaší budoucnosti

Vlákna na CPU Vlákna v systému se nejčastěji vytváří pomocí: POSIX API OpenMP Výkonnostní nevýhoda: O vzniku/yániku vlákna musí být informován OS (hlavně plánovač)

POSIX vlákna POSIX threads (pthreads) je knihovna funkcí v jazyce C pro psaní vícevláknových aplikací. POSIX API obsahuje funkce pro: správu vláken (vytvoření, zrušení, ) synchronizaci a spolupráci mezi vlákny (uzamykání sdílených prostředků) plánování a spouštění vláken Vhodné spíše pro MIMD aplikace: Aplikace typu server-klient (WWW server, tiskový server) Pro I/O nebo GUI Pro SIMD aplikace zbytečně složité

OpenMP základy Zpracováno dle Blaise Barney, Lawrence Livermore National Laboratory Co je to OpenMP? sjednocené API pro programování vícevláknových aplikací. Jak OpenMP funguje? Ve vybraných částech kódu (dále označovaných jako paralelní bloky = parallel regions) je pomocí fork-join mechanismu vytvořen daný počet vláken a tak je tento paralelní blok řešen vícevláknově. Mimo tyto paralelní bloky existuje pouze jedno vlákno hlavního procesu. Pozn. Nedoporučuje se míchat tento způsob vytváření a zániku threadů POSIX thready.

Jak udělat program vícevláknový? Stanovit si, které části kódu (nejčastěji cykly) mají běžet vícevláknově pomocí OpenMP direktiv = vytvoříme paralelní bloky Stanovit pro jednotlivé proměnné jejich OpenMP vlastnosti. V rámci paralelních bloků se vyhnout "thead-unsafe" operacím. Zkompilovat program pomocí "gcc -fopenmp -O3", první volba je pro zpracování OpenMP, druhá zapíná optimalizace kompilátoru. Je zakázáno vyskočit ven nebo vskočit zvenčí dovnitř paralelního bloku.

Efektivita Kvůli Amdahlovu zákonu, je třeba co největší (časovou) část programu napsat paralelně Ale díky tomu, že vytvoření a zánik vláken má jistou režii, je snaha vytvořit spíše menší počet paralelních bloků. Je snaha co nejvíce se vyhýbat zápisu do sdílených proměnných. Kód v kritických sekcích by měl být co nejkratší.

Ukázka OpenMP #include <omp.h> int main () { int var1, var2, var3; //zde pracuje jen hlavni vlakno procesu (serial code) //nasleduje paralelni blok #pragma omp parallel private(var1, var2) shared(var3) { Uvnitr paralelniho bloku pracuje vice vlaken... Promenne var1, var2 jsou privatni = kazde vlakno v tomto bloku ma vlastni Promenna var3 je sdilena vsemi vlakny } //Na konci bloku se nove vznikla vlakna zrusi} //opet pracuje jen hlavni vlakno procesu (serial code)

Počet vláken Počet vzniklých vláken je řízen těmito výrazy (v tomto pořadí, důležitý je první platný výraz) 1. pokud je uvedena, vyhodnotí se if. Pokud není splněna, bude provádět jako sekvenční kód. 2. pokud je uvedena, provede se dle nastavení num_threads 3. pokud bylo uvedeno, provede se dle nastavení při posledním volání fci omp_set_num_threads() 4. pokud je uvedena, provede se dle nastavení proměnné prostředí OMP_NUM_THREADS 5. v závislosti na implementaci nebo dynamicky.

Direktiva "parallel" Možné parametry jsou: if (podmínka) num_threads (výraz) vlastnosti proměnných (seznam proměnných) = v tomto paralelním bloku budou mít proměnné tyto OpenMP vlastnosti. Přesné chování Je vytvořen daný počet vláken, vlákna jsou očíslována, původní (hlavní vlákno procesu) vlákno má číslo 0. Kód paralelního bloku je zduplikován na všechny vlákna a začne se provádět. Na konci paralelního bloku je implicitní bariéra, nově vzniklá vlákna jsou ukončena, dále pokračuje zase jen původní (hlavní vlákno procesu) vlákno. Pokud je z nějakého důvodu jedno z vláken ukončeno během paralelního bloku, jsou ukončeny všchny vlákna a tím i program.

Omezení direktivy "parallel" Paralelního blok nesmí překročit rámec jedné procedury a musí být v jednom programovém souboru. Je zakázáno vyskočit ven nebo vskočit zvenčí dovnitř paralelního bloku. Je dovolena maximálně jedna if (podmínka) před každým paralelním blokem. Je dovolen maximálně jeden num_threads (výraz) před každým paralelním blokem.

Direktiva "for" Konstrukce pro paralelizaci for-cyklu uvniř paralelního bloku, možné parametry jsou: schedule(viz dále) nowait = vlákna na konci paralelního bloku neprovádí bariéru. ordered = pořádí iterací je stejné jako při sekvenčním provádění collapse = slouží pro upřesnění u vnořených cyklů Pozn: Direktivu "parallel" a "for" je mozno spojit do "parallel for

Direktiva "for schedule schedule(typ,velikost) static = Každému vláknu je staticky přiděleno velikost iterací (jdoucích po sobě) cyklu. Pokud není velikost uvedena, jsou iterace rovnoměrně rozděleny mezi vlákna. dynamic = Každému vláknu je dynamicky přiděleno velikost iterací (jdoucích po sobě) cyklu. Když vlákno dokončí, je mu přidělena další část stejné velikosti. Pokud není velikost uvedena, předpokládá se 1. guided = Každému vláknu je dynamicky přiděleno x iterací ( x je počet neprovedených iterací děleno počtem vláken, x je větší nez velikost kromě posledního kousku) cyklu. Když vlákno dokončí,je mu přidělena další část stejné velikosti. Pokud není velikost uvedena, předpokládá se 1. runtime = Rozhodnutí o plánování je odloženo až do okamžiku provedení dle proměnné prostředí OMP_SCHEDULE. auto = Plánování je necháno na kompilátoru a OS.

Kritické sekce Direktiva "single = specifikuje část paralelního bloku, kterou provádí pouze jedno vlákno Možné parametry jsou: nowait = vlákna na konci paralelního bloku neprovádí bariéru. Direktiva "master = specifikuje část paralelního bloku, kterou provádí pouze master vlákno (to s číslem vlákna rovným 0), ostatní vlákna zpracovávají kód následující po této části bloku. Direktiva "critical = specifikuje část paralelního bloku, kterou může současně provádět pouze jedno vlákno (kritická sekce). Možné parametry jsou: jméno = části se stejným názvem jsou brány jako jedna kritická sekce. Všechny části bez jména jsou také brány jako jedna kritická sekce. Direktiva "atomic = specifikuje paměťové operace, které mají být atomické.

Vlastnosti proměnných Určují vlastnosti proměnných vzhledem k paměťovým operacím. Pozor!!! Pokud budou vlastnosti použity na pointer, aplikují se pouze na tento pointer nikoliv na data na která ukazuje.

Vlastnosti proměnných vlastnost shared = určuje, že daná proměnná bude sdílena všemi vlákny. vlastnost private = určuje, že daná proměnná bude lokální ve vlákně, tozn. že každé vlákno bude mít nezávislou instanci této proměnné. Proměnná je vytvořena jako neinicializovaná.

Vlastnosti proměnných vlastnost firstprivate = určuje, že daná proměnná bude lokální ve vlákně, tozn. každé vlákno bude mít nezávislou instanci této proměnné. Proměnná je vytvořena s původní hodnotou, kterou měla před vstupem do paralelního bloku. vlastnost lastprivate = určuje, že daná proměnná bude lokální ve vlákně, tozn. že každé vlákno bude mít nezávislou instanci této proměnné. Hodnota proměnná z poslední iterace bude překopírována do proměnné hlavního vlákna procesu (bude platná po skončení paralelního bloku).

Vlastnosti proměnných vlastnost default = určuje, jakou vlastnost budou mít defaultně všechny proměnné použité v paralelním bloku (pokud nebude uvedeno jinak). vlastnost reduction = určuje, že daná proměnná bude lokální ve vlákně, tozn. že každé vlákno bude mít nezávislou instanci této proměnné. Po skončení bloku se na všechny instance použije redukční operace a výsledek bude zapsán do proměnné hlavního vlákna procesu (bude platný po skončení paralelního bloku). Možné operace jsou: +, *, -, &, ^, Omezení: Musí se jednat o proměnné jednoduchého typu. V nadřízeném bloku musí být deklarovány jako SHARED. Operace nesmí být přetížena pro daný datový typ. Pro reálné datové typy operace nemusí být asociativní. Každý blok může obsahovat i více proměnných pro redukci ale každou maximálně jednou.

Příklad redukce #include <omp.h> int main () { int i, n, chunk; float a[100], b[100], result; /* Some initializations */ n = 100; chunk = 10; result = 0.0; for (i=0; i < n; i++) { a[i] = i * 1.0; b[i] = i * 2.0; } #pragma omp parallel for \ default(shared) private(i) \ schedule(static,chunk) \ reduction(+:result) for (i=0; i < n; i++) result = result + (a[i] * b[i]); printf("final result= %f\n",result); }

OpenMP operace Operace "barrier = specifikuje bariéru (část kódu, kde na sebe všechny vlákna "počkají" a dále jdou zase všechny) Operace "flush = násilně vyvolá čtení a zápis daných proměných do/z paměti. Možné parametry jsou: seznam proměnných. Operace "omp_get_wtime = vrátí číslo (typu double), které udává uběhnutý čas od nějakém (implementačně závislého) okamžiku v minulosti. Nejčastěji se používá jako párové volání pro zjištění např. doby trvání cyklu, doby trvání programu apod.

OpenMP operace Operace "omp_set_num_threads(int i) = programově změní počet vytvořených vláken v následujících paralelních blocích. Musí být volán ze sekvenční části předcházející paralelnímu bloku. Efekt zůstává v platnosti do dalšího volání. Parametrem je požadovaný počet vláken. Operace "omp_get_num_threads = vrátí počet vláken v aktuálním paralelním bloku. V sekvenční části vrací 1.

Operace s OpenMP zámky Operace omp_init_lock(omp_lock_t *x) = inicializuje OpenMP zámek (mutex) s počáteční hodnotou odemčeno. Operace omp_destroy_lock(omp_lock_t *x) = zruší (inicializovaný) OpenMP zámek (mutex). Operace omp_set_lock(omp_lock_t *x) = pokusí se zamknout OpenMP zámek (mutex). V případě neúspěchu se vlákno uspí. Operace omp_test_lock(omp_lock_t *x) = pokusí se zamknout OpenMP zámek (mutex). V případě neúspěchu vrací 0. Operace omp_unset_lock(omp_lock_t *x) = odemkne OpenMP zámek (mutex).