V pátek 6. a sobotu 7. března proběhl v pražském sídle Nejvyššího kontrolního úřadu (NKÚ) Hackathon veřejné správy 7.1. Publikovány byly vytvořené aplikace. V kategorii projektů rozvíjených z krajského kola zvítězil tým „Mackokládi“. Čtyři středoškoláci ze Dvora Králové uspěli s aplikací KompaZ. Jde o digitálního průvodce, který pomůže s rychlou a srozumitelnou orientací v životních i krizových situacích „krok za krokem“. Aplikace
… více »QGIS, svobodný desktopový GIS, byl vydán v nové hlavní verzi 4.0. Změny zahrnují několik nových analytických a editačních funkcí, rozšíření podpory 3D, více možností úprav uživatelského rozhraní či mnoho dalších zlepšení použitelnosti. Řada 3.44 má aktualizace plánovány do září.
Dan Blanchard vydal knihovnu pro Python chardet v nové verzi 7.0.0. S novou verzí byla knihovna přelicencována z LGPL na MIT. Souhlasili s tím všichni přispěvatelé? Dan Blanchard souhlasy vůbec neřešil. Zaúkoloval umělou inteligenci (Claude), aby knihovnu zcela přepsala a výslovně jí nařídil, aby nepoužila žádný LGPL kód. Dan Blanchard tvrdí, že se jedná o clean room design. Protistrana argumentuje, že umělá inteligence byla trénována
… více »Andy Nguyen si na svou herní konzoli PlayStation 5 (PS5) pomocí exploitu Byepervisor nainstaloval Linux (Ubuntu). V Linuxu si spustil Steam a PS5 tak proměnil v Steam Machine. Na PS5 může hrát hry, které jsou vydané pouze pro PC a jsou na Steamu [Tom's Hardware].
Správce sbírky fotografií digiKam byl vydán ve verzi 9.0.0. Jedná se o větší vydání provázené aktualizacemi knihoven. Mnoho dílčích změn se vedle oprav chyb týká uživatelského rozhraní, mj. editace metadat.
Byla vydána verze 2026 distribuce programu pro počítačovou sazbu TeX s názvem TeX Live (Wikipedie). Přehled novinek v oficiální dokumentaci.
Jihokorejská Národní daňová služba (NTS) zabavila kryptoměnu Pre-retogeum (PRTG) v hodnotě 5,6 milionu dolarů. Pochlubila se v tiskové zprávě, do které vložila fotografii zabavených USB flash disků s kryptoměnovými peněženkami spolu se souvisejícími ručně napsanými mnemotechnickými obnovovacími frázemi. Krátce na to byla kryptoměna v hodnotě 4,8 milionu dolarů odcizena. O několik hodin ale vrácena, jelikož PRTG je extrémně nelikvidní, s denním objemem obchodování kolem 332 dolarů a zalistováním na jediné burze, MEXC [Bitcoin.com].
Komunita kolem Linuxu From Scratch (LFS) vydala nové verze knih s návody na instalaci vlastního linuxového systému ze zdrojových kódů Linux From Scratch 13.0 a Beyond Linux From Scratch 13.0. Pouze se systemd.
Byla vydána nová stabilní major verze 25.12 linuxové distribuce primárně určené pro routery a vestavěné systémy OpenWrt (Wikipedie). Jedná se o nástupce předchozí major verze 24.10. Přehled novinek v poznámkách k vydání. Podporováno je více než 2200 zařízení.
Na čem pracují vývojáři webového prohlížeče Ladybird (GitHub)? Byl publikován přehled vývoje za únor (YouTube). Odstraněn byl veškerý kód napsaný ve Swiftu. JavaScriptový engine LibJS byl reimplementován v Rustu.
Když se nad tím zamyslím, tak já vlastně o Linuxu vůbec nepíšu. Všechno co dělám běží i pod Windows a v současnosti na programování používám nejvíce VS2005.Nevadí, důležité je že to neběží jen pod Windows.
Ještě by mohlo umět uložit kód funkce jako objektový soubor pro slinkování s C/C++ kompilátorem a bylo by to dokonalé. 
zajímavé, na takhle nízké úrovni jsem se vykreslovacím procesem (jakožto skalní příznivec SDL) nikdy nezabýval, rád jsem se něco přiučil, děkuji za výborný článek
BlitJit je nízkoúrovňová knihovna pro práci s grafikou pro C++, která je založená na just-in-time kompilaci grafických funkcí. V minulých zápiscích jsem představoval knihovnu AsmJit, která se stala srdcem knihovny BlitJit.
Od prvního vydání knihovny AsmJit už uběhl nějaký ten pátek, tato knihovna se stále zlepšuje a nabývá nových vlastností. Při práci na knihovně BlitJit jsem si uvědomil, že je zapotřebí i něco víc než jen strohý assembler a přidal jsem do knihovny AsmJit i další třídu „Compiler“. Tato třída umožňuje vytvářet funkce pro různé volací konvence (calling conventions) a podporuje dokonce 32 a 64 bitů. O třídě Compiler bych chtěl v budoucnu napsat samostatný zápisek, nyní chci ale ukázat jen možnosti knihovny BlitJit.
Díky knihovně AsmJit a zmíněné třídě Compiler je tedy možné knihovnu BlitJit použít pro architektury x86 a x64 v 32bitovém i 64bitovém módu. Zatím jsem zkoušel jen 32bitový Windows a 64bitový Linux (moje kombinace OS), ostatní až časem (pod 64bitovým Windows očekávám chyby).
Při podrobném prozkoumání ostatních grafických knihoven zjistíme, že každá knihovna potřebuje nízkoúrovňové grafické funkce, které se starají o kompozici pixelů. Tyto funkce většinou bývají napsané v C nebo se používají optimalizace pro MMX, SSE, atd... Když se kdokoliv na tyto funkce podívá podrobně, zjistí, že mají hodně společného. Každá funkce většinou pracuje nad nějakým polem (nejčastěji zdroj a cíl, ale při operaci s konstantní barvou jen cíl). Snahou většiny programátorů v této oblasti je maximálně optimalizovat tyto nízkoúrovňové funkce, protože na nich většinou závisí celkový výkon grafické knihovny.
Problém ručně psaných optimalizací je ten, že každá optimalizace se dělá přesně pro daný pixel formát (předem specifikovaný formát, podle kterého jsou pixely uložené v paměti) a s přibývající podporou více formátů nebo jejich vzájemným mixováním přibývá i nutný počet funkcí pro jejich efektivní zpracování. Protože některé knihovny obsahují opravdu široké spektrum formátů, ve kterých jsou uloženy pixely, řeší se tento problém tak, že zpracování probíhá ve více fázích:
Pokud si to spočítáme, zjistíme, že kompozitní operace pro běžnou operaci může znamenat až 4 fáze (2xFetch, 1xComposite a 1xStore). Každá fáze navíc znamená degradaci výkonu (je to vlastně poměr mezi obecnou implementací a výkonem, čím obecnější implementace, tím menší výkon a naopak). V praxi se to řeší tak, že se píší specializované implementace pro konkrétní formáty a kompozitní operace. Pokud implementace neexistuje, použije se obecná (slow path).
Poslední dobou se snažím navrhovat knihovny tak, aby je bylo možné bez sebemenších problémů používat i jinde - minimalizace závislostí, nepoužívat stl, výjimky a rtti. S knihovnou BlitJit to není jiné. Jediné, co je potřeba pro zkompilování je knihovna AsmJit, na které je celý proces just-in-time kompilace založený.
Knihovna obsahuje třídu pro definování formátu pixelů (PixelFormat) a kompozitní operace (Operation). Formát pixelů je v současnosti implementován jen ARGB32-Premultiplied, ale kompozitní operace už je možné používat všechny (zatím jsou implementované jen operace, které definovali Porter & Duff a něco navíc).
Další třídy, které se používají jsou Generator (jedná se o hlavní třídu, která generuje JIT kód, viz dále) a MemoryManager (třída pro uchovávání a cachování již vytvořeného JIT kódu). V budoucnu se API ale určitě změní, bude potřeba přidávat formáty, kompozitní operace a přidat podporu pro efektivní vykreslování textu a transformace.
Třída Generator umí vytvořit funkce následujících prototypů:
// Broken in new version typedef void (BLITJIT_CALL *FillSpanFn)( void* dst, const UInt32 src, SysUInt len); // Implemented typedef void (BLITJIT_CALL *BlitSpanFn)( void* dst, const void* src, SysUInt len); // Not Implemented typedef void (BLITJIT_CALL *BlitSpanMaskFn)( void* dst, const void* src, const void* mask, SysUInt len); // Implemented typedef void (BLITJIT_CALL *BlitRectFn)( void* dst, const void* src, SysInt dstStride, SysInt srcStride, SysUInt width, SysUInt height); // Not Implemented typedef void (BLITJIT_CALL *BlitRectMaskFn)( void* dst, const void* src, const void* mask, SysInt dstStride, SysInt srcStride, SysInt maskStride, SysUInt width, SysUInt height);
Kde dst je vždycky cílový buffer, src je zdrojový buffer nebo jedna složka (v případě FillSpanFn), len/width je šířka a height výška (s výškou je potřeba zadat i dstStride a srcStride pro skoky na další / předchozí řádek). Funkce se dají vytvořit pomocí generátoru. Vstup pro generátor je třída Compiler (definovaná v knihovně AsmJit, zde je serializován asm kód) a požadované formáty a druh kompozitní operace.
Pokud chce někdo použít knihovnu BlitJit, musí vzít v úvahu, že se jedná o nízkoúrovňovou knihovnu. Je potřeba několik kroků k tomu, aby se vytvořil JIT kód požadovaných parametrů. Například, pokud chci vytvořit funkci, která pro zdrojový a cílový formát ARGB32 provede operaci CompositeOver, musím zavolat následující kód:
// Memory manager nám usnadní alokaci paměti BlitJit::MemoryManager memmgr; // Compiler bude obsahovat serializovaný kód AsmJit::Compiler c; // Generátor potřebuje Compiler, kam bude kód serializovat BlitJit::Generator gen(&c); // Vytvoření požadované funkce ARGB32 <- ARGB32 : CompositeOver gen.fillSpan( BlitJit::Api::pixelFormats[BlitJit::PixelFormat::ARGB32], BlitJit::Api::pixelFormats[BlitJit::PixelFormat::ARGB32], BlitJit::Api::operations[BlitJit::Operation::CompositeOver]); // Cast ukazatele na funkci, podobné jako reinterpret_cast<> BlitJit::FillSpanFn fn = AsmJit::function_cast<BlitJit::FillSpanFn>(memmgr.submit(c));
Nyní jsme vytvořili funkci, kterou můžeme začít ihned používat, a která by měla být optimalizovaná pro současný procesor (nyní jsou implementovány optimalizace jen pro SSE2). Každá takto vytvořená funkce většinou obsahuje 1 hlavní cyklus, ve kterém je zpracováváno více pixelů současně a 2 cykly malé, které se používají na zarovnání cílového bufferu a zpracování posledních pixelů, které se nevešly do hlavního cyklu.
Třída MemoryManager pomáhá s alokací paměti, ve které může být spuštěný kód a ukládá do ní vygenerované funkce. Do třídy Compiler je serializován výstup z generátoru, který je pomocí memmgr.submit() převedený na opravdový strojový kód. Funkce memmgr.submit() vrací ukazatel na vytvořenou funkci. Jedná se o poslední krok, dočasné instance třídy Compiler a Generator by měly následně zaniknout.
Jen pro představu, asm kód, který tato funkce vygeneruje pro 32bitový x86 procesor vypadá takto (jedná se o log, stdcall konvence):
; BlitJit::Generator::blitSpan() - ARGB32 <- ARGB32 : CompositeOver L1: push ebx push ebp push esi L2: mov ecx, [esp + 24] mov edx, [esp + 16] mov ebx, [esp + 20] mov ebp, 0x4317D0 pxor xmm0, xmm0 movdqa xmm1, [ebp] cmp ecx, 0x4 jl L7 xor esi, esi sub esi, edx and esi, 0xF jz L5 shr esi, 0x2 sub ecx, esi L4: movd xmm2, [ebx] movd xmm4, [edx] punpcklbw xmm2, xmm0 punpcklbw xmm4, xmm0 pshuflw xmm6, xmm2, 0xFF pxor xmm6, [ebp + 16] pmullw xmm4, xmm6 paddusw xmm4, xmm1 movdqa xmm6, xmm4 psrlw xmm4, 0x8 paddusw xmm4, xmm6 psrlw xmm4, 0x8 paddusb xmm4, xmm2 packuswb xmm4, xmm4 movd [edx], xmm4 add ebx, 0x4 add edx, 0x4 dec esi jnz L4 mov esi, edx and esi, 0x3 jnz L7 L5: sub ecx, 0x4 jc L7 .align 16 L6: movdqu xmm2, [ebx] pxor xmm3, xmm3 pcmpeqb xmm3, xmm2 pmovmskb esi, xmm3 and esi, 0x8888 cmp esi, 0x8888 jz L9 movdqa xmm4, [edx] movdqa xmm3, xmm2 movdqa xmm5, xmm4 punpcklbw xmm2, xmm0 punpckhbw xmm3, xmm0 punpcklbw xmm4, xmm0 punpckhbw xmm5, xmm0 pshuflw xmm6, xmm2, 0xFF pshuflw xmm7, xmm3, 0xFF pshufhw xmm6, xmm6, 0xFF pshufhw xmm7, xmm7, 0xFF pxor xmm6, [ebp + 16] pxor xmm7, [ebp + 16] pmullw xmm4, xmm6 pmullw xmm5, xmm7 paddusw xmm4, xmm1 paddusw xmm5, xmm1 movdqa xmm6, xmm4 movdqa xmm7, xmm5 psrlw xmm4, 0x8 psrlw xmm5, 0x8 paddusw xmm4, xmm6 paddusw xmm5, xmm7 psrlw xmm4, 0x8 psrlw xmm5, 0x8 paddusb xmm4, xmm2 paddusb xmm5, xmm3 packuswb xmm4, xmm5 movdqa [edx], xmm4 L9: add ebx, 0x10 add edx, 0x10 sub ecx, 0x4 jnc L6 add ecx, 0x4 jz L8 sub ecx, 0x2 jc L10 .align 8 L7: movq xmm2, [ebx] movq xmm4, [edx] punpcklbw xmm2, xmm0 punpcklbw xmm4, xmm0 pshuflw xmm6, xmm2, 0xFF pshufhw xmm6, xmm6, 0xFF pxor xmm6, [ebp + 16] pmullw xmm4, xmm6 paddusw xmm4, xmm1 movdqa xmm6, xmm4 psrlw xmm4, 0x8 paddusw xmm4, xmm6 psrlw xmm4, 0x8 paddusb xmm4, xmm2 packuswb xmm4, xmm4 movq [edx], xmm4 add ebx, 0x8 add edx, 0x8 sub ecx, 0x2 jnc L7 L10: add ecx, 0x2 jz L8 movd xmm2, [ebx] movd xmm4, [edx] punpcklbw xmm2, xmm0 punpcklbw xmm4, xmm0 pshuflw xmm6, xmm2, 0xFF pxor xmm6, [ebp + 16] pmullw xmm4, xmm6 paddusw xmm4, xmm1 movdqa xmm6, xmm4 psrlw xmm4, 0x8 paddusw xmm4, xmm6 psrlw xmm4, 0x8 paddusb xmm4, xmm2 packuswb xmm4, xmm4 movd [edx], xmm4 add ebx, 0x4 add edx, 0x4 L8: L3: pop esi pop ebp pop ebx ret 0xC
64bitový kód vypadá podobně, akorát se používají 64bitové registry a zpracování parametrů funkce a návrat vypadá trochu jinak.
Pro testování a odladění knihovny jsem používal pár png ikonek, které jsou z projeku Crystal Project Icons. Tyto ikonky jsem zkoušel míchat a testoval jsem i rychlost vykreslení 10.000 ikon (rozměry 128x128).
Screenshoty z testovací aplikace jsou na konci blogu
Rychlost knihovny je podle mě výborná. Momentálně jsem se soustředil na optimalizace pro SSE2, které opravdu postrádám v mnoha známých knihovnách (včetně pixman/cairo, X server, gdk-pixbuf, agg, evas, imlib2, v současném provedení i Qt). Vygenerovaný kód zatím neobsahuje instrukce jako jsou prefetch/prefetchw a ukládání pomocí Non-Thermal hintu (movntq, movntdq, ...).
Při vlastních testech mi vychází, že operace CompositeOver a další kompozitní operace jsou asi o 50% rychlejší než ty, co jsou implementované v knihovně pixman/cairo. Při volení nestandardních formátů by rychlost měla být ještě lepší. Zkoušel jsem porovnávat i s knihovnou SDL a kompozitní operaci CompositeOver mám rychlostně podobnou. Problém je v tom, že SDL používá nepřesný výpočet (který zrychlí algoritmus až o 30%), takže to srovnání je spíš orientační.
Knihovna je součástí moji diplomové práce, ve které se věnuji tématu návrhu a optimalizace grafické knihovny, která je schopná použít vlákna a jit kompilaci pro maximální efektivitu. Osobně by se mi nejvíce líbilo, kdyby se dala vytvořit podpora BlitJit například pro cairo, ale to by chtělo opravdu pořádné testování a doladění veškerých detailů, na které v současnosti není moc času;)
Tiskni
Sdílej: