it-swarm-eu.dev

Kompilátor JIT pro C, C ++ a podobné

Existuje nějaký kompilátor just-in-time pro kompilované jazyky, jako jsou C a C++? (První jména, která přicházejí na mysl, jsou Clang a LLVM! Ale nemyslím si, že by je v současné době podporovaly.)

Vysvětlení:

Myslím, že software by mohl těžit z runtime profilování zpětné vazby a agresivně optimalizované rekompilace hotspotů za běhu, dokonce i pro kompilované jazyky, jako jsou C a C++.

Optimalizace řízená profilem provádí podobnou práci, ale s tím rozdílem by JIT byl flexibilnější v různých prostředích. V PGO spustíte binární před uvolněním. Poté, co jej uvolníte, nebude používat žádné zpětné vazby prostředí a vstupů shromážděné za běhu. Takže pokud se změní vstupní vzor, ​​je to výkonnostní pokuta sondy. Ale JIT funguje dobře i za těchto podmínek.

Domnívám se však, že je kontroverzní, pokud přínos sestavení výkonu JIT převažuje nad jeho vlastní režií.

33
Ebrahim Mohammadi

[Viz historie úprav pro zcela jinou odpověď, která je nyní v zásadě zastaralá.]

Ano, existuje několik kompilátorů JIT pro C a/nebo C++.

CLing (jak jste si asi ze hry mohli myslet) je založeno na Clang/LLVM. Funguje to jako tlumočník. To znamená, že mu dáte nějaký zdrojový kód, zadáte příkaz, aby se spustil, a spustí se. Důraz je zde kladen především na pohodlí a rychlé kompilace, nikoli na maximální optimalizaci. Ačkoli je to technicky odpověď na samotnou otázku, není to opravdu vhodné pro záměr OP.

Další možností je NativeJIT . To odpovídá otázce poněkud jinak. Zejména nepřijímá zdrojový kód C nebo C++, zkompiluje ho a provede. Spíše je to malý kompilátor, který můžete zkompilovat do svého programu C++. Přijímá výraz, který je v podstatě vyjádřen jako EDSL uvnitř vašeho C++ programu, a vygeneruje z něj skutečný strojový kód, který pak můžete spustit. To se hodí mnohem lépe s rámcem, ve kterém můžete většinu svého programu zkompilovat s běžným kompilátorem, ale máte několik výrazů, které nebudete vědět, až za běhu, které chcete provést s něčím, co se blíží optimální rychlosti provádění.

Pokud jde o zjevný záměr původní otázky, myslím, že základní bod mé původní odpovědi stále platí: zatímco kompilátor JIT se může přizpůsobit takovým věcem, jako jsou data které se liší od jednoho provedení k druhému, nebo se dokonce dynamicky mění během jediného provedení, realita je taková, že se tím zásadně málo liší alespoň zpravidla. Ve většině případů spuštění kompilátoru za běhu znamená, že se musíte vzdát docela optimalizace, takže o to nejlepší, co obvykle doufáte, je to, že je blízko tak rychle, jak by produkoval běžný kompilátor.

Ačkoli je možné postulovat situace, kdy informace dostupné kompilátoru JIT by mohly umožnit vygenerování podstatně lepšího kódu než konvenční kompilátor, v praxi k tomu dojde Zdá se, že je docela neobvyklý (a ve většině případů, kdy jsem byl schopen ověřit jeho fungování, bylo to opravdu kvůli problému ve zdrojovém kódu, nikoli se statickým kompilačním modelem).

33
Jerry Coffin

Ano, existují kompilátory JIT pro C++. Z hlediska čistého výkonu si myslím, že optimalizace profilu řízená optimalizací (PGO) je stále lepší.

To však neznamená, že kompilace JIT se v praxi dosud nepoužívá. Například Apple používá LLVM jako JIT pro jejich potrubí OpenGL. To je doména, kde máte za běhu výrazně více informací, které lze použít k odstranění velkého množství mrtvých kódů.

Další zajímavou aplikací JIT je Cling, interaktivní tlumočník C++ založený na LLVM a Clang: https://root.cern.ch/cling

Zde je ukázka relace:

[cling]$ #include <iostream>
[cling]$ std::cout << "Hallo, world!" << std::endl;
Hallo, world!
[cling]$ 3 + 5
(int const) 8
[cling]$ int x = 3; x++
(int) 3
(int const) 3
[cling]$ x
(int) 4

Nejedná se o projekt hraček, ale ve skutečnosti se používá například v CERNu k vytvoření kódu pro Large Hadron Collider.

11
Philipp Claßen

C++/CLI je nervózní. Je samozřejmé, že C++/CLI není C++, ale je to docela blízko. To znamená, že JIT společnosti Microsoft nedělá super chytré/roztomilé druhy optimalizací chování za běhu, o které žádáte, alespoň ne podle mých znalostí. Takže to opravdu nepomůže.

http://nestedvm.ibex.org/ přeměňuje MIPS na Java bytecode, který by byl poté rozcuchán. Problém s tímto přístupem z vaší otázky spočívá v tom, že zahodíte do doby, než se dostane do JIT, mnoho užitečných informací.

7
Logan Capaldo

Za prvé, předpokládám, že byste chtěli spíše trasovací jit než metodu.

Nejlepším přístupem by bylo zkompilovat kód do llvm IR a poté přidat do trasovacího kódu před vytvořením nativního spustitelného souboru. Jakmile se kódový blok stane dostatečně dobře využitým a jakmile se shromáždí dostatek informací o hodnotách (nikoli o typech jako v dynamických jazycích) proměnných, pak lze kód překompilovat (z IR) pomocí strážců na hodnoty proměnných.

Zdá se, že si vzpomínám, že došlo k určitému pokroku ve výrobě c/c ++ jit in clang pod názvem libclang.

2
dan_waterworth