Problémy jazyka Python
- Účelem paralelizace je maximalizovat použití výpočetních zdrojů, nejde tím ale Python trochu naproti?
- Python je znám pro svou nevýkonnost
- Dynamický jazyk - spoustu režie za běhu programu (GC, typová kontrola…)
- Omezení GIL - nejvýše jedno vlákno může současně běžet v jednom procesu
- použití více vláken pro výpočet náročné na CPU nepřináší žádné výrazné zrychlení (pokud nějaké)
- Vlákna mají v Pythonu ale stále využití, pokud čekají často na externí události (čtení/zápis, databáze, obsluha klienta…)
- Framework asyncio
- poskytuje základ pro tvorbu a správu síťové komunikace, webové servery, práci s databází, fronty
Řešení výkonnosti a paralelizace v Pythonu
- Existuje řada přístupů, jak obejít omezení GIL a celkově zrychlit výpočet
Použití knihovny multiprocessing
- Před verzí CPython 3.13 se dalo opravdové paralelizace dosáhnout pouze vytvářením nových procesů
- Tvorba a správa procesů však je obecně dražší a náročnější (nesdílejí paměť) než u vláken
Použití jiných implementací Pythonu
- Existují jiné implementace Pythonu, které se mírně odchylují od standardní implementace (CPython)
- Některé implementují techniky, které mohou běh programu za jistých okolností zrychlit
JIT kompilace
- Dynamicky kompiluje často používané části kódu do strojového kódu, který se za běhu programu dále optimalizuje
- Výhodné obzvláště pro dlouhotrvající procesy
- Příklady:
- Numba - optimalizován pro číselné operace
- využívá NumPy a jeho struktur
- není potřeba v kódu provádět žádné výrazné změny
- příslušně označený kód se zkompiluje do strojového kódu, rychlost pak může být porovnatelný s kódem psaný v C či C++
- nejvíce při práci s čísly, poli a NumPy funkcemi
- možnost paralelizace operací, které nevyžadují Python interpret
- (nepřestupují ke specifickým objektům Pythonu)
- PyPy (Python in Python)
- Jyphon - implementace v Javě - bez GIL
- překlad do mezikódu, který je následně vykonáván v JVM
- možné integrovat kód v Pythonu do aplikací v Javě
- IronPython - obdoba Jyphon pro .NET - bez GIL
- Příklad Numba
Statická kompilace do nižšího jazyka
- Kompilace kódu v Python do sdílené knihovny v C nebo C++ (v podobě
'.so'
nebo .dll
), který lze přímo volat v Pythonu
- Příklady jsou: Cyphon, mypyc…
- rozšiřují syntaxi o typové notace, které umožňují optimalizaci kompilovaného kódu
- Cyphon
- umožňuje také volat funkce existujících knihoven C/C++
- V souboru
.pyx
zapisujeme kód v Pythonu, které se následně zkompiluje do C/C++
- MyPyc
- využívá statické typování MyPy
Externí knihovny psané v nízkoúrovňových jazycích
- Především v C a C++
- Optimalizované pro úlohy náročné na procesor
- především zpracovávání velkých číselných dat
- Python pak slouží spíše jako jakási řídící vrstva, která deleguje náročné výpočty externím modulům implementovaných v nižších jazycích
- Zpracování v jiném jazyce nejsou limitovány GIL
Nepoužívat Python
- Požadujeme-li aplikace náročný výpočet na procesoru, měli bychom spíše zvolit jiný jazyk
Externí nástroje využívající paralelizaci
- Existují knihovny, které ke složitým výpočtům na velkých datech využívají paralelizaci
Dask
- Knihovna navržena pro paralelizaci při zpracovávání velkých dat, ale i pro distribuované výpočty (clustery)
- Umožňuje pracovat s daty, které překračují velikost dostupné paměti - “out-of-core computing”
- Vlastnosti:
- Plánování úloh (tasks)
- úlohu rozděluje do menších částí a sestavuje graf závislostí, podle kterého se následně řídí výpočet
- X → Y → Z
- Y → W
- Před vykonáním Z musí být vykonán Y, přičemž W může běžet souběžně se Z
- Správa grafu úloh
- Dask před samotným výpočtem provádí analýzu a optimalizaci grafu
- Líné vyhodnocování
- výpočet není výkonán ihned, ale je vložen do grafu úloh
- Vykonávání plánovaných úloh lze realizovat pomocí:
- ThreadedScheduler
- využívá vláken v Pythonu pro paralelní vykonávání úloh
- vhodný pro úlohy čekající na I/O
- MultiprocessingScheduler
- pro parelelní běh jsou vyhrazeny samostatné procesy
- DistributedScheduler
- vykonávání napříč stroji či clustery
- Využívá knihoven jako NumPy, Pandas či jiných pro rychlejší nízkoúrovňové výpočty
Další…