DynamickýPřekladPrakticky
Z Denik
(→IV. Promluvte si s překladačem: Direktivy) |
(→V. Promluvte si s překladačem: Profily, bioinformatika a předpoklady) |
||
Řádka 42: | Řádka 42: | ||
Ač tyto triky používáme primárně pro psaní interpretrů, tak jsou obecně užitečné. Pojďme se tedy mrknout, jak si promluvit s překladačem a zrychlit nějakou úlohu z ''bioinformatiky''. Vezmeme si '''BooleanNetwork''' a zkusme ji nějak rychle prohledat. Když porovnáme klasickou (HotSpot) Javu a kód přeložený v Truffle módu, tak Truffle je o 20% rychlejší. Stačí použít direktivu '''@ExplodeLoop'''. Máte-li velké datové struktury, které chcete prohledávat, tak "částečné vyhodnocování" v Truffle módu, je přesně to, co byste měli prozkoumat! | Ač tyto triky používáme primárně pro psaní interpretrů, tak jsou obecně užitečné. Pojďme se tedy mrknout, jak si promluvit s překladačem a zrychlit nějakou úlohu z ''bioinformatiky''. Vezmeme si '''BooleanNetwork''' a zkusme ji nějak rychle prohledat. Když porovnáme klasickou (HotSpot) Javu a kód přeložený v Truffle módu, tak Truffle je o 20% rychlejší. Stačí použít direktivu '''@ExplodeLoop'''. Máte-li velké datové struktury, které chcete prohledávat, tak "částečné vyhodnocování" v Truffle módu, je přesně to, co byste měli prozkoumat! | ||
- | '''Assumption''' (předpoklad) lze použít pro globální spekulaci. Díky tomu je možné | + | '''Assumption''' (předpoklad) lze použít pro globální spekulaci. Díky tomu je možné přenastavením nějakého stavu zinvalidovat všechny již přeložené kódy, které na tomto stavu závisí. Nakonec si ještě zkusíme napsat polymorfní keš na prohledávání telefonního seznamu. Ale k tomu bude potřeba se ještě vrátit v příští lekci. |
- | + | ||
- | Nakonec si ještě zkusíme napsat polymorfní keš na prohledávání telefonního seznamu. Ale k tomu bude potřeba se ještě vrátit v příští lekci. | + | |
=== IV. Talk 2 Compiler: Assumptions & Caches === | === IV. Talk 2 Compiler: Assumptions & Caches === |
Verze z 17. 6. 2021, 08:27
Seminář na MatFyz pro letní semestr 2019, který pokračuje na jaře 2021.
Dynamický Překlad Prakticky
Jaký je nejrychlejší programovací jazyk? Může být JavaScript rychlejší než Céčko? Existuje jednoduchý způsob, jak si napsat jazyk, který bude opravdu rychlý? Musíme opravdu psát všechny knihovny znovu a znovu? Jak se implementuje debugger? A jak profiler? Kolik to dá práce? To jsou otázky, na které v průběhu semináře budeme hledat a nalezneme odpovědi.
Budeme používat GraalVM, což je nejrychlejší virtuální stroj, který shodou okolností pomáhá vyvíjet tým z pražské pobočky OracleLabs. Díky tomu to bude seminář praktický, přibližující nejnovější trendy ve vývoji virtuálních strojů. Žádná otázka nebude tabu - o GraalVM víme úplně vše!
Cílem bude ukázat si na výhody a zádrhele dynamického překladu. Pochopit, co překladač ve skutečnosti dělá a naučit se dorozumět se s ním - tedy programovat tak, abyste z dynamického překladu v GraalVM získali co nejvíce. Máte-li vlastní programovací jazyk, vezměte si jej s sebou - uděláme jej rychlejší!
A pokud to někoho bude opravdu bavit, tak může pokračovat v létě při studijní stáži v OracleLabs v Jinonicích.
Osnova přednášek
I. Představujeme nejrychlejší univerzální virtuální stroj
Záznam úvodní přednášky. Začínáme historií NetBeans, protože se k přednášce na MatFyzu určitě hodí. Nemůže chybět zmínka o návrhu API a mé knížce Practical API Design, aby bylo zřejmé, proč se tomuto kurzu říká Practical Dynamic Compilation! Následuje takové to tradiční povídání o tom, co GraalVM umí a jak je snadné a jednoduché to nainstalovat (pomocí utilitky gu), použít a jak strašně rychle pak lze počítat Eratesthénovo síto v libovolném jazyce. Není to nic převratného, ale pokud jste to ještě někdo neviděl, tak je to vhodná upoutávka k záznamům dalších lekcí.
Je naše GraalVM implementace Ruby 10-krát rychlejší než jakákoli jiná? Jak dlouho může trvat vypsat všechna prvočísla? Co je vstupem a co je výstupem Graal překladače? Jakým nástrojem můžeme zkoumat, co Graal překladač vlastně uvnitř dělá? Jak napsat vlastní jazyk? Jak vložit implementaci existujícího dynamického jazyka do vlastního Java programu? Dá se to potom také ladit? V NetBeans? Ve Chrome Dev Tools? Má cenu psát interpretr Céčka?
II. Jak fungují moderní překladače?
V záznamu druhé přednášky si nejprve dokončíme úvod z minula a povíme si, jak se zbavit Javovské virtuální mašiny! Dynamický překlad je skvělý, ale vyžaduje spoustu metadat. Naštěstí můžeme GraalVM využít na překlad Java kódu do EXáče! To je důležitý střípek v tom jak GraalVM ekosystém funguje. Ale protože nás primárně bude zajímat překlad dynamických jazyků, tak si hned také představíme základní trik, který z dynamických jazyků dělá něco, z čeho lze vygenerovat efektivní strojový kód. Pořádně to prodiskutujeme a pak...
Od 35-té minuty následuje skutečné povídání o moderních překladačích: Jak vlastně překládat Javu, Céčko a jiné staticky typované jazyky? Pro osvěžení, co to vlastně překladače jsou a jak fungují, nám výborně poslouží přednáška kolegy Chrise Seatona. Opravdu je lepší psát překladač v C++ než v Javě? Chcete psát překladač a nebo vás baví psát vlastní garbage collector!? Nevynalézejte znovu kolo a raději si vyklonujte graal repozitoř. Vaše oblíbené IDE (ať NetBeans nebo VSCode či Ideal Graph Visualizer a nebo i jiné) ty zdrojáky bez problémů otevře. Pak už můžete přidávat breakpointy do zdrojáků překladače, spouštět si vaše programy a koukat, jak se překládají. Můžete si i změnit sémantiku překladu, vypsat si ladící hlášky či něco podobného. Jak vaše aplikace, tak váš překladač jsou v Javě a ve vašem vývojovém prostředí se chovají úplně stejně. Avšak ne jen laděním je živ překládající inženýr! My milujeme grafy z překladače, které radostně zkoumáme v IGV. Stahujte, zkoumejte jednotlivé fáze překladu a bezostyšně přeskakujte mezi IR grafy různých fází, vašimi zdrojáky, zdrojáky překladače. Bez IGV ani ránu!
III. Jak překládají moderní překladače?
Třetí díl záznamu zahajuje pět minut technických problémů, ale pak již následuje vytvoření Maven projektu v IGV a jeho zkoumání ze všech možných úhlů. Použijte -Dgraal.Dump=:1 a -Dgraal.PrintGraph=Network a pojďme se podívat na grafy překladu. S gettery, které se inlinují či neinlinují. Prozkoumejme, jak vypadá IR graf výpočtu průměru. Se smyčkou či bez ní. Jak funguje bytecode parser? Jak se generuje assembler? Jak si můžeme vypsat strojový kód z příkazové řádky? Třída Phase a její implementace poskytují různé optimalizace: Kanonikalizace uzlů. Znovupoužití hodnot. Eliminace zámků. Jak může debugger spolupracovat s IGV? Přes graph.getDebug().forceDump(...). Tomáš Zezula nám představí GraphBuilderPluginy a dostane domácí úkol...
IV. Promluvte si s překladačem: Direktivy
Čtvrtá část záznamu zkoumá k čemu všemu lze Graal překladač vlastně použít. Začínáme ukázkou Tomáše Zezuly používající GraphBuilderPlugin k nahrazení SecurityManageru no-op konstantou (do 12-té minuty). Takže místo JEP-411, který se snaží SecurityManager smazat, bychom jej tam mohli nechat a jen eliminovat jakoukoli zátěž, která je s ním spojená, nepoužívá-li se. Zajímavé, že?
Propagace konstant je důležitá optimalizace, kterou budeme hojně používat při práci s Talk 2 Compiler demo projektem. A můžeme začít s Trufflem. Co je to RootNode.execute? Co je to CallTarget? To je způsob jak z Java módu běhu a překladu přeskočit do "Truffle překladu". Jak se liší Truffle IGV graf od klasického IGV grafu z Javy? Má final vliv v Javě? A má jej při Truffle překladu? Překlad pro "instanci" RootNodu. Lze používat CompilationFinal a měnit hodnotu takového políčka - natrénujte si svůj kód na hodnoty, které skutečně používáte. Dejte si ale pozor, ať ten kód natrénujete správně! Kdykoli měníte @CompilationFinal pole, tak nezapomeňte zavolat transferToInterpreterAndInvalidate()! Použijte TruffleBoundary na vyskočení z "Truffle módu" do "normální" Javy. Tím zabráníte inlinování příliš velkého množství kódu z mnoha metod.
V. Promluvte si s překladačem: Profily, bioinformatika a předpoklady
Opakování je matka moudrosti a tudíž pátá část záznamu stručně shrne specifika Truffle překladu a pak pokračuje ve vysvětlování různých dynamických optimalizačních triků. Spekulujme na to, že se nějaký parametr nemění. Trochu program natrénujeme a jen sledujeme, jak se vše zoptimalizuje. A abychom nemuseli pořád psát to samé, tak použijeme profily: ConditionProfile či ValueProfile či BranchProfile či createCountingProfile().
Ač tyto triky používáme primárně pro psaní interpretrů, tak jsou obecně užitečné. Pojďme se tedy mrknout, jak si promluvit s překladačem a zrychlit nějakou úlohu z bioinformatiky. Vezmeme si BooleanNetwork a zkusme ji nějak rychle prohledat. Když porovnáme klasickou (HotSpot) Javu a kód přeložený v Truffle módu, tak Truffle je o 20% rychlejší. Stačí použít direktivu @ExplodeLoop. Máte-li velké datové struktury, které chcete prohledávat, tak "částečné vyhodnocování" v Truffle módu, je přesně to, co byste měli prozkoumat!
Assumption (předpoklad) lze použít pro globální spekulaci. Díky tomu je možné přenastavením nějakého stavu zinvalidovat všechny již přeložené kódy, které na tomto stavu závisí. Nakonec si ještě zkusíme napsat polymorfní keš na prohledávání telefonního seznamu. Ale k tomu bude potřeba se ještě vrátit v příští lekci.
IV. Talk 2 Compiler: Assumptions & Caches
- Explain assumptions
- `warmWelcome` with assumptions
- ExplodeLoop example
- `Chain`
V. Talk 2 Compiler: Nodes & Specializations
- Interpreter for reading array elements
- Name the method `executeCompute` to work better with DSL
- Let it work with `int` and `double`
- Rewrite using specializations
VI. Memory Management
- Garbage Collector
- VirtualFrame
- Descriptor
- DynamicObject
- Shape
VII. Graal Self
- Let's look at real language
- PE parser
- Interop
VIII. JIT vs. AOT překlad
- Go, Java, go!
- jargraal vs. libgraal
- Using native-image to implement `native` methods
IX. Interop mezi jazyky
- Messages. "Mounting" trees.
- Exposing data structures to languages
X. Tools & Instruments
- Making your language "toolable"
- Source section
- Tags
- Show how to debug in NetBeans
- Writing an instrument
- Debugger, profiler, code coverage, language server protocol, NetBeans
- node.js
- Mixing Java and JavaScript & co.
XI. Static Languages with LLVM
- Sulong - interpret C, Rust, atd.
- Truffle NFI
XII. Writing bytecode interpreter
- Espresso - Java interpreter
- Sulong - bitcode interpreter
XIII. Real Language Problems
- implementace FFI jazyku jako Ruby/Python/R
- yield in JavaScriptu
- lazy evaluation in R
Appendix A: Contributing To Open Source
- Overview of the repositories
- Python, JavaScriptem, Ruby, FastR, Espresso
- mx tooling
- Signing OCA
https://github.com/jtulach/bf https://www.youtube.com/watch?v=FJY96_6Y3a4