abclinuxu.cz AbcLinuxu.cz itbiz.cz ITBiz.cz HDmag.cz HDmag.cz abcprace.cz AbcPráce.cz
AbcLinuxu hledá autory!
Inzerujte na AbcPráce.cz od 950 Kč
Rozšířené hledání
×
dnes 14:00 | Nová verze

Bylo vydáno openSUSE Leap 15.2. Přehled novinek v nejnovější verzi této linuxové distribuce v do češtiny přeloženém oznámení o vydání a v poznámkách k vydání.

Ladislav Hagara | Komentářů: 0
dnes 12:44 | Nová verze

Apache Guacamole, řešení pro vzdálený přístup k počítačům pomocí protokolů VNC, RDP a SSH z webového prohlížeče, bylo vydáno ve verzi 1.2.0. Přehled novinek v oficiálním oznámení. Zdůraznit lze podporu SAML 2.0, Wake-on-LAN, nové rozhraní pro přepínání mezi sezeními nebo překlad webového rozhraní do češtiny.

Ladislav Hagara | Komentářů: 0
včera 22:55 | Komunita

Nadace Raspberry Pi oznámila, že OpenVX 1.3 API lze nově používat také na Raspberry Pi. OpenVX je standard pro akceleraci aplikací počítačového vidění. Vyzkoušet lze ukázkové příklady.

Ladislav Hagara | Komentářů: 0
včera 22:11 | Zajímavý článek

Možná jste taky někdy zápasili s tiskem formulářů nebo šablon, které pořád ne a ne vyjít ve správné velikosti. Článek Tisk v přesném měřítku (PDF, PPD, CUPS) popisuje příběh hledání jedné takové chyby v GNU/Linuxu.

xkucf03 | Komentářů: 5
včera 08:00 | Nová verze

Byla vydána nová verze 4.8 živé linuxové distribuce Tails (The Amnesic Incognito Live System), jež klade důraz na ochranu soukromí uživatelů a anonymitu. Přehled změn v příslušném seznamu. Tor Browser byl aktualizován na verzi 9.5.1. Thunderbird na verzi 68.9.0. Linux na verzi 5.6.0. Opravena byla řada bezpečnostních chyb.

Ladislav Hagara | Komentářů: 1
30.6. 23:11 | Zajímavý projekt

Na Kickstarteru byla spuštěna kampaň na podporu tabletu CutiePi postaveného na Raspberry Pi, konkrétně na Compute Module 3+ Lite. Předobjednat jej lze za 198 dolarů. Expedice je plánována na listopad.

Ladislav Hagara | Komentářů: 4
30.6. 22:11 | Zajímavý článek

Na serveru Techrights.org vyšel článek The GNU Project is Bleeding Into Microsoft, který upozorňuje na podezřele se množící případy projektů, které jsou přesměrované z webových stránek GNU na GitHub (proprietární software a služba provozovaná Microsoftem). Článek poukazuje i na to, že k řadě přesměrování došlo po tom, co byl Richard Stallman (zakladatel hnutí GNU a nadace FSF) „vyhnán“ z vedení FSF (resp. odstoupil po agresivní

… více »
xkucf03 | Komentářů: 59
30.6. 18:00 | Komunita

Projekt KDE přešel na GitLab. Vlastní instance již běží na invent.kde.org. Další info v příspěvku na blogu GitLabu. Před dvěma lety byl na GitLab přesunut vývoj GNOME.

Ladislav Hagara | Komentářů: 5
30.6. 17:33 | Nová verze

Vyšel webový prohlížeč Mozilla Firefox 78.0. Jedná se o vydání s prodlouženou podporou (ESR). Počínaje tímto vydáním jsou k dispozici také poznámky k vydání pro podniky, kde jsou shrnuty změny týkající se zabezpečení, kompatibility a chování zvláště právě v podnikovém prostředí. Jednou z takových změn je odstranění podpory TLS 1.0 a 1.1.

Fluttershy, yay! | Komentářů: 2
30.6. 13:22 | Zajímavý článek

Nová čísla časopisů od nakladatelství Raspberry Pi: MagPi 95 (pdf), HackSpace 32 (pdf) a Hello World 13 (pdf).

Ladislav Hagara | Komentářů: 2
Používáte některé open-source řešení [protokol] pro šifrovaný instant messaging?
 (23%)
 (30%)
 (5%)
 (11%)
 (18%)
 (6%)
 (12%)
 (26%)
Celkem 286 hlasů
 Komentářů: 32, poslední 28.6. 17:51
Rozcestník

AsmJit - JIT Assembler pro C++

21.1.2009 21:41 | Výběrový blog | poslední úprava: 31.8.2009 14:22

Tento blog byl smazán autorem

       

Hodnocení: 100 %

        špatnédobré        

Tiskni Sdílej: Linkuj Jaggni to Vybrali.sme.sk Google Del.icio.us Facebook

Komentáře

Vložit další komentář

21.1.2009 22:47 zde | skóre: 9 | blog: Linuch | Brno
Rozbalit Rozbalit vše Re: AsmJit - JIT Assembler pro C++

Proč? www.gnu.org/software/lightning/ Je to jednoduché, portabilní, velmi dobře zdokumentované, a jako bonus to není C++ :)

Táto, ty de byl? V práci, já debil.
21.1.2009 23:25 Deleted [8409] | skóre: 14 | blog: darkblog
Rozbalit Rozbalit vše Re: AsmJit - JIT Assembler pro C++
V zápisku jsem na některé věci zapomněl. Za zmínku zde by stálo, že svůj kód jsem založil na assembleru, který používá Google V8. Jejich koncepce se mi ale moc nezamlouvala, tak jsem se rozhodl to celé přepsat (nyní je tam z V8 snad už jen Label a Displacement).

Syntaxe je navržená tak, aby co nejvíc odpovídala té intelovské, kterou vám nabízí většina debuggérů a disasm nástrojů.

Podívejte na pár příkladů:
using namespace AsmJit;

X86 a;

// mov eax, dword ptr[ebx + 16]
a.mov(eax, dword_ptr(ebx, 16));

// mov dword_ptr [eax + ebx * 4 + 16], edx
a.mov(dword_ptr(eax, ebx, TIMES_4, 16), edx);

// mov ah, al
a.mov(ah, al);

// mov al, byte ptr[ecx]
a.mov(al, byte_ptr(ecx));

// add dword_ptr [esi], eax
a.add(dword_ptr(esi), eax);

// addps xmm1, dqword ptr [eax]
a.addps(xmm1, dqword_ptr(eax));
Pokud lighting používáte, tak můžete odpovědět přepsáním těch instrukcí pro lighting, uvidíte, že těch C maker pro jednotlivé instrukce je potřeba mnohem víc. Druhá věc je podpora pro odhalování chyb. AsmJit vám některé chyby odhalí už při kompilaci a runtime chyby je možné odhalit v debug módu (a nekontrolovat je při release).

Třeba následující kód vám AsmJit nezkompiluje:
// esi není sse registr
a.addps(esi, dqword_ptr(eax));
Další zápor oproti C a makrům je pro mě i licence. AsmJit můžete díky MIT vložit do kteréhokoliv projektu a linkovat staticky.
22.1.2009 00:29 zde | skóre: 9 | blog: Linuch | Brno
Rozbalit Rozbalit vše Re: AsmJit - JIT Assembler pro C++

Všechno je to 1:1, s výjimkou toho intelího SIB, to se skutečně musí napsat jako 3 instrukce, a protože to nemá peephole, tak z toho i 3 instrukce vylezou. IMHO malá cena za to že nebudete vázán na konkrétní procesor. Ta EA se 3 termy a ještě se scale se ale používá minimálně, a obyčejný base + index nebo base + immediate adresování Lightning samozřejmě pro i386 kompiluje jako jedinou instrukci.

// mov dword_ptr [eax + ebx * 4 + 16], edx
lshi(R1, R1, 2); // ebx *= 4
addr(R0, R0, R1); // eax += ebx
stxi(R0, 16, R2);
Táto, ty de byl? V práci, já debil.
22.1.2009 01:34 Deleted [8409] | skóre: 14 | blog: darkblog
Rozbalit Rozbalit vše Re: AsmJit - JIT Assembler pro C++
Hmm popravdě, udržovat něco takového, jak jste teď napsal, bych nechtěl:) Bez těch komentářů není na první pohled absolutně vidět, o co jde. Vím, že pro x86 by to i v lightingu bylo na jeden řádek, ale tak dobrou syntax pro konkrétní architekturu, kterou nabízí AsmJit, v lighting nedosáhnete.

Navíc ta přenositelnost u asm podle mě není potřeba. Bavíme se o rozdílných architekturách, rozdílných technikách optimalizací kódu (na úrovni asm) a rozdílných možností procesoru (MMX, SSE, ALTIVEC). Pro X86-64 bit budu psát trochu jiný kód než pro X86-32 bit. Těch 16 registrů navíc se prostě dá využít a pokud něco dělám, tak to chci dělat pořádně i využít to naplno (jinak bych se asi nezabýval JIT:-) )
22.1.2009 09:52 zde | skóre: 9 | blog: Linuch | Brno
Rozbalit Rozbalit vše Re: AsmJit - JIT Assembler pro C++

Nojo, jenže když bude uživatel pracovat s konkrétním procesorem, pak je celá knihovna jen jakýmsi glorifikovaným wrapperem, jehož smysl je hlavně v tom že místo:

memcpy(out, "\x89\x4C\x98\x10", 4); out += 4;

můžete psát

asm.mov(dword_ptr(eax, ebx, TIMES_4, 16), ecx);

To první je jednodušší, výrazně rychlejší, a abych pochopil co to dělá tak mi stačí disasembler. To druhé vyžaduje studium zdrojáku, tedy dohledání funkcí, hodnot konstant apod, v případě C++ pak ještě prohledávání base tříd a pod. Pravda, jednu "vysokoúrovňovou" funkci to asi mít bude, bude to umět vytvářet a následně resolvovat dopředné odkazy, na to memcpy() nestačí. Netvrdím že je to k ničemu, když člověk tvoří něco co zrovna potřebuje, tak to obvykle opravdu potřebuje, ale přijde mi že je to v podstatě jednoduchá věc zbytečně zabalená do nějakého api. U Lightning ty makra mají smysl, protože pro každý CPU se implementují jinak. Tady si tím už jistý nejsem.

Táto, ty de byl? V práci, já debil.
22.1.2009 11:31 Deleted [8409] | skóre: 14 | blog: darkblog
Rozbalit Rozbalit vše Re: AsmJit - JIT Assembler pro C++
Tak pokud vám stačí disasm a každou instrukci chcete psát v podobě "\x89\x4C\x98\x10", tak vám AsmJit určitě nic nepřinese, ale já bych se o takový zdroják starat nechtěl. AsmJit knihovna vám nenutí prakticky nic, jen za vás dělá ještě nějaké kontroly na chyby, které se můžou při psaní asm stát. Upozornění na špatné parametry vám dělá už při kompilaci.
// OK
asm.mov(dword_ptr(eax, ebx, TIMES_4, 16), ecx);
// Chyba, špatné parametry (díky C++ už při kompilaci .cpp souboru)
asm.mov(dword_ptr(eax, 16, ebx, TIMES_4), ecx);
Kdybych například ve vašem příkladu udělal chybu, tak se jen vygenerují jiné opcodes a chybu zjistíte až při běhu aplikace (v ideálním případě to spadne, ale nemusí).
// záměrná chyba
"\x89\x4C\x10\x98"
V dalším zápisku bych to chtěl trošku víc rozebrat i s nějakým lepším příkladem, na kterém by šlo vidět lepší využití.
22.1.2009 12:47 zde | skóre: 9 | blog: Linuch | Brno
Rozbalit Rozbalit vše Re: AsmJit - JIT Assembler pro C++

Tak jsem si to konečně stáhnul, rozbalil, a trochu prohlédl. Je to docela čitelné, jen si myslím že autor zbytečně používá úplně nepotřebné abstrakce. Třeba nechápu proč je Register třída, proč to není jednoduše enum. Nebylo by třeba blbnout s operator==() apod, a bylo by to čitelnější. To že něco existuje v nějaké učebnici C++ ještě neznamená že je to dobré, a že je to třeba používat.

Táto, ty de byl? V práci, já debil.
22.1.2009 13:22 Deleted [8409] | skóre: 14 | blog: darkblog
Rozbalit Rozbalit vše Re: AsmJit - JIT Assembler pro C++
No ty třídy pro registr pochází už z V8, originální komentář je takový:
// CPU Registers.
//
// 1) We would prefer to use an enum, but enum values are assignment-
// compatible with int, which has caused code-generation bugs.
//
// 2) We would prefer to use a class instead of a struct but we don't like
// the register initialization to depend on the particular initialization
// order (which appears to be different on OS X, Linux, and Windows for the
// installed versions of C++ we tried). Using a struct permits C-style
// "initialization". Also, the Register objects cannot be const as this
// forces initialization stubs in MSVC, making us dependent on initialization
// order.
//
// 3) By not using an enum, we are possibly preventing the compiler from
// doing certain constant folds, which may significantly reduce the
// code generated for some assembly instructions (because they boil down
// to a few constants). If this is a problem, we could change the code
// such that we use an enum in optimized mode, and the struct in debug
// mode. This way we get the compile-time error checking in debug mode
// and best performance in optimized code.
//
struct Register ...
Já jsem to překopal v tom smyslu, že jsem ke každému registru ještě přidal jednoznačné ID, ze kterého jdou vyčíst i jiné informace než číslo registru pro X86. Tímto způsobem je možé psát assert() u některých funkcí, a kontrolovat jestli není v kódu chyba. Některé instrukce, kde se používají MMX nebo SSE registry vám zase nepustí jako parametr GP registr.

Napříklád toto:
// OK
a.mov(al, ah);
a.mov(eax, ebx);

// Chyba, u mov nelze použít MMX a SSE2 registry, na to jsou
// jiné instrukce (movd, movq, movdq). Ve staré verzi, která
// se dá momentálně stáhnout ty MMX ještě jdou, ale nově
// jsem to vyhodil do jiné instrukce, přesně jak je to popsané
// v Intel manuálu.
// (chyba bohužel se projeví až v runtime)
a.mov(mm0, mm1);
a.mov(xmm0, xmm1);
Ale neprojde třeba ani, když si spletete velikost ukazatele:
// OK
a.mov(al, byte_ptr(eax));
a.mov(eax, dword_ptr(eax));

// Chyba
a.mov(al, dword_ptr(eax));
a.mov(eax, byte_ptr(eax));
V budoucnu plánuju přidat těch assertů mnohem víc, teď jsem na to neměl zase tolik času to dovést k dokonalosti :-)

PS: Pro jednoduchý debug je assert() provedený v tomto smyslu ((int*)NULL) = 0, tím aplikace spadne, takže je ladění hračka o něco zábavnější, než hledat číslo řádku, atd :)
22.1.2009 14:35 zde | skóre: 9 | blog: Linuch | Brno
Rozbalit Rozbalit vše Re: AsmJit - JIT Assembler pro C++
We would prefer to use an enum, but enum values are assignment-compatible with int

Řekl bych, že to není pravda.

$ more t.cc
enum foo { a, b, c };
foo bar() { return 100; }
void baz() { foo x = 1; }
$ gcc -c t.cc
t.cc: In function ‘foo bar()’:
t.cc:2: error: invalid conversion from ‘int’ to ‘foo’
t.cc: In function ‘void baz()’:
t.cc:3: error: invalid conversion from ‘int’ to ‘foo’
Táto, ty de byl? V práci, já debil.
22.1.2009 14:39 zde | skóre: 9 | blog: Linuch | Brno
Rozbalit Rozbalit vše Re: AsmJit - JIT Assembler pro C++

Aha, tak int => enum sice řve, ale enum => int bohužel bez jakéhokoliv warningu projde, a to i při -Wall :/

Táto, ty de byl? V práci, já debil.
22.1.2009 15:06 Let_Me_Be | skóre: 20 | blog: cat /proc/idea/current | Brno
Rozbalit Rozbalit vše Re: AsmJit - JIT Assembler pro C++
Ano presne takle ma take enum fungovat. Presne dle standardu.
Linked in profil - Můj web - Nemůžete vyhrát hádku s blbcem. Nejdřív vás stáhne na svoji úroveň a pak ubije zkušenostmi.
22.1.2009 01:03 Sinuhet | skóre: 31
Rozbalit Rozbalit vše Re: AsmJit - JIT Assembler pro C++
Mohl byste prihodit nejaky realny priklad, na kterem bude videt vyhoda vasi knihovny oproti pouziti asm(...)? Mozna jsem neco straslive nepochopil, ale protoze jde o doslovnou kopii syntaxe normalniho assembleru, nelze podle meho cekat zadne velke uspory jak ve velikosti (a citelnosti) zdrojaku, tak zkompilovane binarky.
22.1.2009 01:11 Andrej Herceg | skóre: 43
Rozbalit Rozbalit vše Re: AsmJit - JIT Assembler pro C++
Predpokladám, že to bude fungovať tak, že tam bude nejaká knižnica, ktorá bude z nejakého (napr. grafického) algoritmu generovať pomocou týchto funkcií výsledný kód strojový (čiže zaujímavejšia asi bude tá časť, ktorá bude ten algoritmus spracovávať).
22.1.2009 01:13 Andrej Herceg | skóre: 43
Rozbalit Rozbalit vše Re: AsmJit - JIT Assembler pro C++
*strojový kód :)

Každopádne som zvedavý, ako si to potom poradí s MMX, SSE... (kedže vygenerovať pomocou tých funkcií rýchly algoritmus nie je zrovna najjednoduchšie)
22.1.2009 01:37 Deleted [8409] | skóre: 14 | blog: darkblog
Rozbalit Rozbalit vše Re: AsmJit - JIT Assembler pro C++
Rozdíl je v tom, že při použití asm() ve zdrojáku generujete statický kód, ale pomocí AsmJit generujete kód dynamický při běhu aplikace (a můžete ho přiohýbat vašim požadavkům). Ta kopie syntaxe je právě proto, aby co nejvíc připomínala tu syntax, kterou píšete v asm (mi osobně se nejvíc líbí intel, takže jsem použil tu) a zabral jste co nejmíň času učením se něčeho nového.
22.1.2009 09:28 zde | skóre: 9 | blog: Linuch | Brno
Rozbalit Rozbalit vše Re: AsmJit - JIT Assembler pro C++
No, a co vám brání to "přiohnutí" udělat #ifdefy, přeložit všechny varianty, a za runtime jednu z nich vybírat např. přes function pointer? Pokud jsou těch variant jednotky maximálně desítky, tak je to nejjednodušší řešení.
Táto, ty de byl? V práci, já debil.
21.1.2009 23:01 Non_E | skóre: 24 | blog: hic_sunt_leones | Pardubice
Rozbalit Rozbalit vše Re: AsmJit - JIT Assembler pro C++
Vůbec tomu nerozumím (moje chyba), ale vypadá to, že jsi do toho dal hodně práce a třeba to bude někomu užitečné. Líbí se mi to.
Only Sith deals in absolutes.
hikikomori82 avatar 21.1.2009 23:21 hikikomori82 | skóre: 18 | blog: foobar | Košice
Rozbalit Rozbalit vše Re: AsmJit - JIT Assembler pro C++
Prečo si radšej nebastlíš vlastnú distribúciu ako každý normálny človek?
21.1.2009 23:36 petr_p | skóre: 59 | blog: pb
Rozbalit Rozbalit vše Re: AsmJit - JIT Assembler pro C++

Vypadá to úžasně.

Jen jakožto uživatel Gentoo nechápu, v čem spočívá výhoda JIT, když stejnou práci může udělat už překladač v době překladu. (A jako bonus se programátor nemusí trápit s assemblerem.)

22.1.2009 00:08 Deleted [8409] | skóre: 14 | blog: darkblog
Rozbalit Rozbalit vše Re: AsmJit - JIT Assembler pro C++
Děkuju, ta syntaxe byla pro mě opravdu moc důležitá :)

Výhoda JIT spočívá hlavně v tom, kdy chcete optimalizovat místa, které by jste normálně nikdy neoptimalizoval, protože optimalizce pro všechny možnosti je nereálná (moc možností). Kdybych zůstal u počítačové grafiky, tak jako jednoduchý příklad by mohl byt konvertor z jednoho pixel formátu na druhý. Dejme tomu, že to bude lepší konvertor, který umí pracovat s 20 různými formáty. Žádný programátor nezačne psát 20*20 funkcí, ale začne psat obecnější (a pomalejší) funkce, které se pro dosažení výsledku zkombinují (takže v nejhorším případě těch funkcí bude 40, ale pokud budou mít některé formáty hodně společného, vlezeme se i do míň funkcí). V případě architektury X86 máme velké možnosti, jak kód optimalizovat. Nejhorší na tom všem je ale to, že při běhu našeho konvertoru bude třeba uživatel používat jen 4 pixel formáty, ale kvůli obecnější a pomalejší implementaci bude víc čekat.

Koncepce JIT je celkem zajímavá a jsou i nějaké diskuze o optimalizaci knihovny pixman, kterou používá cairo, třeba zde.
22.1.2009 08:08 Let_Me_Be | skóre: 20 | blog: cat /proc/idea/current | Brno
Rozbalit Rozbalit vše Re: AsmJit - JIT Assembler pro C++

Zakladni princip JIT je v tom ze clovek z nejakeho duvodu potrebuje distribuovat jednu binarku na mnoho architektur (typicky binarni distribuce) a presto chce aby mu to jelo alespon trochu rychle. Pokud je mozne distribuovat zdrojove kody postrada JIT z velke casti smysl (i kdyz ano i tady se obcas najde nejake vyuziti).

Linked in profil - Můj web - Nemůžete vyhrát hádku s blbcem. Nejdřív vás stáhne na svoji úroveň a pak ubije zkušenostmi.
22.1.2009 11:28 Kvakor
Rozbalit Rozbalit vše Re: AsmJit - JIT Assembler pro C++
Dalsi vyhoda je cpani konstan primo do kodu - kdysi se to delalo samomodifikujicim se kodem, ale pres JIT kompilaci je to o dost cistci. Sice dnesni procesory maji cache, pipelining, reordering a vselike jine urychlovaci featury, takze to zas tak moc neurychliy (i kdyz, minimalne to zaplaca mene cache), ale v dobach 286 byl sakra rozdil, kdyz se v nejvnitrnejsi smycce nemuselo pro konstanty sahat do pameti, protoze byly primo v instrukci.
22.1.2009 14:06 Let_Me_Be | skóre: 20 | blog: cat /proc/idea/current | Brno
Rozbalit Rozbalit vše Re: AsmJit - JIT Assembler pro C++
A to ma byt vyhoda JITC? To je trochu nesmysl, ne? Kdyz je to konstanta tak se prece vyhodnoti v dobe kompilace, pokud to neni konstanta tak ji musi vyhodnocovat JITC (coz je to same jako kdyby ji vyhodnocoval samotny program).
Linked in profil - Můj web - Nemůžete vyhrát hádku s blbcem. Nejdřív vás stáhne na svoji úroveň a pak ubije zkušenostmi.
22.1.2009 15:36 Kvakor
Rozbalit Rozbalit vše Re: AsmJit - JIT Assembler pro C++
Samozdrejme je myslena konstana z pohledu samoneho JIT generovaneho kodu, z pohledu zbytku programu je to promenna, jejiz hodnota ktera je v dobe prekladu neznama. Napriklad pokud potrebujete pronasobit vsechna cisla v poli nejakym koeficientem, tak bude onen koeficient z pohledu vnitrniho cyklu konstana (tj. vlozi se jako prima hodnota do instrukce), i kdyz z vnejsku to bude bezna promenna predana jako parametr one funkce.

Pro male objemy dat je to samozdrejme neefektivni, protoze JIT kompilace zabere vice casu, nez se usetri, ale staci si predstavit rekneme takovou fotografii z desetimegapixeloveho fotoaparatu, ktera se prevadi z RAWu. U te se behem konverze kazdeho pixelu provadi spousta pronasobeni konstantami (napr. vyvazeni bile), ktere uz z principu nemohou byt zname v dobe prekladu programu, ale jsou zname pred zapocetim samotne operace. A navic se mohou vyloucit skoky, protoze se nemusi pocitat se specialnimi pripady - kazde pouziti JIT muze byt specialni.
23.1.2009 10:01 zde | skóre: 9 | blog: Linuch | Brno
Rozbalit Rozbalit vše Re: AsmJit - JIT Assembler pro C++
Pro uvedené věci se už X let používají SIMD instrukce, které jsou implementované i v mobilech, a pro které marketingová oddělení vymyslela nejrůznější legrační názvy, můj favorit je "intel wireless mmx". Umí to násobit vektor v jednom registru vektorem v druhém registru. Násobit konstantou NELZE (proč taky), musíš ji najdřív narvat do registru. Z toho plyne že násobení konstantou i proměnnou trvá stejně rychle, čili JIT nemá smysl.
Táto, ty de byl? V práci, já debil.
23.1.2009 16:03 Deleted [8409] | skóre: 14 | blog: darkblog
Rozbalit Rozbalit vše Re: AsmJit - JIT Assembler pro C++
SIMD instrukce jsou většinou ve tvaru:
instrukce [x]mm, [x]mm/mem[32|64|128]
Kdyby JIT kompilace pro grafiku neměla smysl, tak nevznikají projekty jako orc nebo genrender. Všechno závisí na znalostech a schopnostech programátora. Věřím, že například cairo by mohlo být klidně 4x rychlejší, ale musel by se najít člověk a hlavně čas na to, aby to někdo mohl implementovat.

Ještě k tomu jit bych dodal to, že při kompilaci na míru můžeme některé konstanty úplně vyhodit nebo předpočítat operace s konstantama, které jsou nutné k výpočtu. Další optimalizace by mohla být například vkládání prefetch instrukcí nebo používat Non Temporal read / write.

jednoduchý JIT by pak mohl vypadat třeba takto:
X86 a;

// eax *= i;
if (i == 0)
{
  // clear: x = 0;
  a.xor(eax, eax);
}
else if (i == 1)
{
  // nop
}
else if (isPowerOf2(i))
{
  // shift instead of multiply: x <<= shiftOf(i);
  a.shl(eax, imm(shiftOf(i));
}
else
{
  // multiply: x *= i
  a.imul(eax, imm(i));
}
Tento jednoduchý příklad ukazuje eliminaci jednoho registru, který může být v inner loop cyklu hodně užitečný.
25.1.2009 21:21 petr_p | skóre: 59 | blog: pb
Rozbalit Rozbalit vše Re: AsmJit - JIT Assembler pro C++

Když jste to nakousl, tak by mě zajímalo, co to ten AsmJit vlastně je? Spíše než jako překladač mi přijde jako optimalizátor, protože vstupem mu je assembler a výstupem opět assembler.

Třeba u výroby funkce složené ze dvou jiných si dokážu přestavit optimalizaci formu minimalizace složeného automatu. Ale takto u explicitního kódu si nedokážu přestavit, jak by taková optimalizace mohla rozumně fungovat. (Něco jiného by bylo, kdyby se JIT-kompilovalo z vysokoúrovňového jazyka (třeba algebraického výrazu) do assembleru).

26.1.2009 00:22 Deleted [8409] | skóre: 14 | blog: darkblog
Rozbalit Rozbalit vše Re: AsmJit - JIT Assembler pro C++
Já myslím, že jste to pochopil dobře. JitAsm jen překládá do binární podoby to, co mu podstrčíte v C++. AsmJit má vlastně jen pokrýt dynamické generování kódu do binárního proudu.

V některém z dalších zápisků bych chtěl ukázat použití na dynamickém kompilování matematického výrazu a následné spuštění. Mám to de fakto hotové, jen k tomu napsat text a vysvětlit, jak to celé funguje:-)

Ještě bych chtěl dodat něco k tomu explicitnímu zápisu. JitAsm je, dalo by se říct, velice nízkoúrovnová knihovna. Neobsahuje třeba alokování registrů, makra pro vytváření funkcí, atd. Tyto věci by se ale můžou implementovat bokem.

Chtěl bych v blízké době vydat verzi s podporou pro 64 bitů a napsat o JitAsm mnohem víc, uvidím jak to bude s časem. Také bych chtěl alespon základní přenositelnost mezi 32 bit a 64 bit kódem (aby se nemusela každá funkce psat úplně zvlášt).

Pokud máte otázky, nebo něčemu nerozumíte, klidně se ptejte;)
kozzi avatar 21.1.2009 23:43 kozzi | skóre: 55 | blog: vse_o_vsem | Pacman (Bratrušov)
Rozbalit Rozbalit vše Re: AsmJit - JIT Assembler pro C++
No já zrovna přemýšlím o něčem s podobnou tématikou. A to o tom udělat virtuální stroj na kterém by se člověk mohl učit asm. Měl by být multiplatformní, co nejvíc modulární, podporovat víc syntaxí a také víc architektur. No jestli toto někdy dokončím a nezůstane jen u mýšlenky, tak budu mít dobrej pocit :-)
Linux je jako mušketýři "jeden za všechny, všichni za jednoho"
22.1.2009 01:40 Deleted [8409] | skóre: 14 | blog: darkblog
Rozbalit Rozbalit vše Re: AsmJit - JIT Assembler pro C++
No pokud vás to zajímá, tak určitě doporučuju nahlédnout do zdrojáků V8. Je to fakt celé hodně zajímavé a těch souborů není ani až tak moc. Každopádně se ale nejedná o nějaký jednoduchý VM;-)
22.1.2009 12:58 Boris Dušek | skóre: 22 | blog: everything
Rozbalit Rozbalit vše Re: AsmJit - JIT Assembler pro C++

Snad Tě potěší, že první nahlášený issue obsahuje i patch ;-) Jinak neuvažoval jsi nad použitím LLVM? Tím by si pak rovnou podporoval všechny architektury (stálo by pak sice si zkontrolovat, jestli to z IR do X86 zkompilovalo stejně (nebo více) efektivně jako Tebou rukou napsaný kód, ale snad funguje dobře, když je okolo něj takový buzz). Každopádně řádka X86 a; je hrozně krásná.

vim ~/.emacs
22.1.2009 13:30 Deleted [8409] | skóre: 14 | blog: darkblog
Rozbalit Rozbalit vše Re: AsmJit - JIT Assembler pro C++
Díky za patch, jsem rád, že to funguje i na OSX:-)

To LLVM mi přijde jako huge projekt pro něco, jako chci dělat já. Vždycky jsem se zajímal o optimalizace na konkrétní architekturu (x86) a zkušenosti s asm celkem mám. Potřebuju generovat jen pár funkcí, které chci mít vysoce optimalizované s použitím klidně i SSE4 a mám pocit, že něco takového je i pro LLVM moc.

Jinak je LLVM určitě zajímavý projekt.

PS: Mrkněte se, jak se dá v asm zoptimalizovat práce s vektorem, myslím, že zatím žádný překladač není něco takového schopen udělat: SSE
31.8.2009 15:04 backup
Rozbalit Rozbalit vše Záloha: AsmJit - JIT Assembler pro C++

Dnes jsem vydal nový projekt, na kterém ve volných chvílích pracuju. Jedná se o JIT překladač assembleru pro C++, který chci použít pro generování blit funkcí pro jednu grafickou knihovnu (FOG). Vytvořit JIT assembler, a pochopit celý princip, na kterém je toto generování kódu založené (generování opcodes) není až tak těžké. Intel X86 je bezesporu komplikovaná architektura, ale s použitím knížky Intel Architecture Software Developers Manual to byla spíš zábava.

Celý JIT je souborem několika tříd v C++, které reprezentují jednotlivé části generování kódu. Obsahuje třídy Register, MMRegister a XMMRegister reprezentující registry. Základní třída Register také může reprezentovat menší registry, které sdílí prostor s 8 základními (třeba AL, AH, AX, ...). Každý registr má přiřazené unikátní ID, ze kterého je možné vyčíst kód registru (v X86 architektuře číslo 0-7), typ registru (GPB, GPW, GPD, MMX, SSE) a velikost registru (to vše je zakódované v malém 8 bitovém neznaménkovém čísle).

Další nutnost pro vytváření JIT assembleru je možnost adresovat místa v paměti. X86 architektura obsahuje poměrně velké možnosti, od jednoduché adresace (např [eax]) až po komplikované adresace (např [eax + 4*edx + 16). Pro adresování je použitá třída Op (zkratka pro Operand), která může obsahovat všechny typy adresací, navíc registry a neměnné hodnoty (immediates). Trída Op vlastné zaobaluje všechny operandy, které je možné při generování kódu použít.

Úplně poslední věc, bez které se při generování kódu nedá obejít jsou labely (nebo návěští). Některými opovrhované goto v C je v asm vlastné jediná možnost, jak dělat podmíněné i nepodmíněné skoky. K definici skoku slouží třída Label. Konstruktor třídy zanechá label jako unbound, to znamená, že pozice skoku ještě nebyla definovaná, ale takto nezinicializovaný label už JE možné použít pro skok na kód, jehož pozice zatím není známá. Pomocí bind() se definuje pozice skoku a tato funkce zárověň opraví všechny místa, které na tuto zatím nedefinovanou pozici ukazovaly.

(Tento odstavec asi není úplně srozumitelný)

Poslední třída, kterou bych chtěl představit, se jmenuje X86. Jak už název napovídá, jedná se o hlavní třídu, která se používá pro samotné generování kódu. Instance třídy si uchovává interní buffer, do kterého přidává emitované instrukce v binární podobě (opcodes). Obsahuje instrukční sadu X86 až po SSE (SSE2 a další přidám v budoucnu).

A k čemu je to dobré?

Vyměnil jsem si pár emailů s lidma, kteří se zajímají o počítačovou grafiku jako já. Dodnes se všechny funkce dělali ručně a jednotlivé možnosti CPU se vždycky implementovaly také jen ručně a mnohdy se na nové možnosti CPU vůbec nedostalo (např. X Server používá maximálně MMX). Pomocí JIT překladače je možné generovat kód dynamicky, za běhu přidávat například nový pixel formát a generovat i kód pro takové funkce, které normálně fungují jako složení z více funkcí. Průběh low level grafické funkce vypadá normálně nějak takto - nahraj a zkonvertuj pixely SRC a DST do formátu ARGB32 -> zkombinuj -> zakóduj výsledné pixely zpět do DST. Pomocí JIT překladače je možné některé speciální (neboli nejčastěji používané) operace zkompilovat na míru a vyhneme se tím vlastně tří konverzí (a zvýšíme výkon).

Dodatek: Konverze se samozřejmě nedělá tam, kde pracujeme s nativním formátem (většinou ARGB32 premultiplied), ale například při blitování obrázku, který je jen RGB24 už konverze probíhá (minimálně 1).

A úplně na závěr úplný příklad toho, jak dynamicky vygenerovat a spustit jednoduchý kód. Zkoušel jsem to ve Windows i v Linuxu, takže případní zájemci můžou hned začít experimentovat a hlásit chyby :-). Zdrojové kódy a tento příklad je možné stáhnout s použitím odkazu na konci zápisku.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "../AsmJit/AsmJitX86.h"

#include "../AsmJit/AsmJitVM.h"

typedef int (*VoidFn)();

int main(int argc, char* argv[])
{
  using namespace AsmJit;

  // Create function by dynamic way
  X86 a;

  // Prolog
  a.push(ebp);
  a.mov(ebp, esp);

  // Mov 1024 to EAX, EAX is also return value.
  a.mov(eax, imm(1024));

  // Epilog
  a.mov(esp, ebp);
  a.pop(ebp);
  a.ret();

  // Alloc execute enabled memory and call generated function
  size_t vsize;
  void *vmem = VM::alloc(a.codeSize(), &vsize, true);
  memcpy(vmem, a.pData, a.codeSize());

  // Cast vmem to VoidFn 
  VoidFn fn = (VoidFn)vmem;
  
  // Call it
  int result = fn();

  // Memory should be freed, but use VM::free() to do that.
  VM::free(vmem, vsize);

  printf("Result from jit function: %d\n", result);
  return 0;
}

Poznámka: Paměť, ve kterém chceme provést exekuci kódu, je nutné alokovat jinak než pomocí malloc(), v Linuxu se používá mmap() a ve Windows VirtualAlloc(). Na obou systémech je možné i paměť dodatečně označit jako EXECUTE (v linuxu pomocí mprotect), ale tímto jsem se zatím nezdržoval.

Knihovnu jsem umístil zde: http://code.google.com/p/asmjit/ pod MIT licencí.

UPDATE:

Na webu je k dispozici nová verze (0.2), byl aplikován patch pro macos (díky) a instrukční sada je nyní kompletní (včetně SSE4). Nyní se budu soustředit spíš na testování a popřípadě přidání podpory pro 64 bit.

Založit nové vláknoNahoru

ISSN 1214-1267   www.czech-server.cz
© 1999-2015 Nitemedia s. r. o. Všechna práva vyhrazena.