5.6.2015
Statistické zpracování velkých objemů dat naráží na malý výkon dnešních procesorů. I když mám pod stolem zaparkovaný docela výkonný stroj, jeho výkon na některé věci prostě nestačí. Snažím se vizualizovat výsledky několika miliónů měření. Zpracování by mělo probíhat interaktivně, při změně některého z parametrů se musí graf na obrazovce okamžitě přepočítat a překreslit. Protože výkon procesoru nestačí, začal jsem výpočty stěhovat do grafické karty. Grafická karta dokáže provádět výpočty paralelně - místo jednoho výpočetního vlákna v procesoru se použije několikanásobně vyšší počet výpočetních vláken v grafické kartě.
Struktura OpenCL programu pro grafickou kartu je odlišná od normálního programu pro hlavní procesor. OpenCL program je v hlavním programu "uložený" jako zdrojový text. Při inicializaci hlavní program nahraje tento zdrojový text do grafické karty a spustí překladač jazyka C v kartě a program se přeloží. Teprve po přeložení se do karty posílají data a spouští se program v grafické kartě.
Už při prvních pokusech jsem narazil na zvláštní chování programů v grafické kartě:
float pi = 3.14159f;
Program by měl do proměnné pi uložit číslo s několika desetinnými místy. Ve skutečnosti se ale dostala do proměnné hodnota 3. Program interpretuje float hodnotu jako integer, ořízne desetinnou část. Jak je to možné? Překladač reaguje na nastavení systémové proměnné prostředí LC_ALL. V mém případě je v této proměnné hodnota cs_CZ.utf8 - čeština. Program nerozezná tečku jako oddělovač desetinných míst a hodnotu interpretuje jako celé číslo. Na překladač je to velmi nezvyklé chování.
Poučení? Před spuštěním programu vždy vynulujte proměnnou LC_ALL, případně další proměnné spojené s locales:
unset LANG unset LC_ALL unset LANGUAGE
Programování OpenCL není příliš rozšířené - na jednoho programátora OpenCL připadá stovka programátorů PHP. Množství informací na internetu tomu odpovídá - o nutnosti nastavit proměnnou LC_ALL se nikde nedočtete, Google žádný takový text nenabídne.
Podobně jako Google nenabídne žádný návod, jak donutit překladač OpenCL interpretovat desetinná čísla správně, nenabídne vám ani nejjednodušší způsob ladění OpenCL programů. OpenCL programy totiž běží na jiném počítači (v grafické kartě), normální ladící program je zde naprosto k ničemu. Mám pro vás jednoduchý tip - použijte funkci printf, například:
printf("%d %f\n", get_global_id(0), input[get_global_id(0));
Řádek při svém běhu vypisuje informaci na konzolu i v případě, že jeho část běží v grafické kartě. Pro spoustu situací stačí i takto jednoduchá informace, abyste si udělali obrázek o tom, co se vlastně děje.