Zašto analizirati efikasnost rada ?
Naizgled je jednostavno izvršiti paralelizaciju već postojećih programa. Delovi programa u kojima se vrši veliki broj aritmetičkih operacija nad nizovima ili matricama se prevodi u kernel funkcije, izvršava paralelno na velikom broju niti i postiže se veliko ubrzanje. Međutim, kada se sagleda detaljnije, nije uvek sve tako jednostavno. Postoji dosta stvari na koje treba obratiti pažnju – manipulacija memorijom, bolje iskorišćenje dostupnih resursa i slično. Ukoliko se neki segment programa ne paralelizuje kako treba, neće biti postignuto željeno ubrzanje, ili jednostavno neće biti maksimalno iskorišćene sve prednosti koje CUDA pruža. Da bi programer bio siguran da je sve urađeno kako treba, treba da izvrši analizu efikasnosti CUDA programa. Jedan od načina je pomoću Parallel Nsight-a, kao što sam već pisala u ovom blogu. Drugi način je pomoću CUDA Visual Profiler-a i to je tema ovog bloga.
Šta je zapravo Visual Profiler ?
Kada se instalira CUDA (drajveri, Toolkit, SDK), pored standardnih “elemenata”, instaliraju se i dodatni alati, između ostalog i CUDA Visual Profiler. Ovaj program praktično predstavlja grafički korisnični interfejs (GUI) za analizu izvršavanja CUDA programa, odnosno za merenje performansi i pronalaženje eventualnih mogućnosti za optimizaciju. Cilj je svakako da se maksimalno iskoristi dostupni potencijal GPU uređaja. Uz pomoć ovog alata, analiza efikasnosti (eng. profiling) je jednostavna, brza i laka. Potrebno je samo startovati ovaj program i sa nekoliko klikova mišem sve potrebne informacije su dostupne u formi izveštaja (dijagrama, tabela, grafika…). Pored samog programa, instalira se i jako dobar User Guide, u kome se mogu naći mnogi korisni saveti. Prilikom analize efikasnosti, ne bi bilo loše da se koristi i dokument CUDA C Programming Best Practices Guide (takođe se instalira u okviru CUDA “paketa”), u kome se mogu naći saveti za optimizaciju CUDA programa.
Posle verzije 3.1, CUDA Visual Profiler i još jedan alat OpenCL Visual Profiler su sastavljeni u jednu aplikaciju, pod novim imenom - Compute Visual Profiler.
Kako pristupiti Visual Profiler-u ?
Najčešće se prilikom instalacije CUDA softvera, ikonica Visual Profiler-a postavlja na desktop. Ako to nije slučaj, najlakše je pokrenuti Visual Profiler iz Start menija: Start -> All Programs -> NVIDIA Corporation -> CUDA Toolkit -> 3.2 -> Compute Visual Profiler.
Kada se pokrene program, pojavljuje se dialog box sa opcijama za otvaranje postojećeg projekta, kreiranje novog itd.

U nastavku teksta ću korak po korak objasniti kako se analizira rad CUDA programa, i to programa čiji je source code već objašnjen u blogu br. 8.
Korišćenje Visual Profiler-a
Klikom na taster Create u startup dialog box-u (prikazan je na prethodnoj slici), otvara se novi dialog u kome treba uneti ime i željenu lokaciju projekta.

Zatim je potrebno uneti podatke vezane za program koji se analizira – lokaciju exe verzije, kao i “radni” folder. Napomena: pre početka analize primenom Visual Profiler-a neophodno je kompajlirati CUDA program, jer se za analizu koristi Release exe verzija.

U okviru ovog dialog box-a nalaze se još dva taba, tu su ponuđeni svi parametri koje je moguće analizirati, pa se tu može vršiti selekcija – šta analizirati, a šta ne.


Za parametre koji se nalaze na listi u okviru Other Options taba se već na osnovu naziva može zaključiti na šta se odnose, tako da ih neću dodatno objašnjavati. Ali nazivi parametara u okviru Profiler Counters taba su malo manje “opisni”, tako da ću objasniti šta oni predstavljaju:
- gld uncoalesced: broj neusklađenih pristupa globalnoj memoriji (operacije čitanja)
- gld coalesced: broj usklađenih pristupa globalnoj memoriji (operacije čitanja)
- gst uncoalesced: broj neusklađenih pristupa globalnoj memoriji (operacije pisanja)
- gst coalesced: broj usklađenih pristupa globalnoj memoriji (operacije pisanja)
- local load: broj operacija čitanja iz lokalne memorije
- local store: broj operacija pisanja u lokalnu memoriju
- instructions: broj instrukcija
- branch: broj uslovnih grananja kroz koje prolazi jedna nit
- divergent branch: broj različitih uslovnih grananja u okviru jedne grupe niti
- cta launched: broj blokova niti nad kojima su izvršavane kernel funkcije
- warp serialize: broj niti u okviru jedne grupe koje moraju da čekaju kraj izvršavanja druge niti (zbog konflikata u pristupu deljivoj ili konstantnoj memoriji)
Nakon izbora svih željenih opcija, klikom na taster Launch, počinje analiza programa. Zapravo, exe verzija se pokreće nekoliko puta, da bi se izanalizirali svi željeni aspekti. Nakon toga, otvara se glavni prozor Visual Profiler-a, u kome se u delu Output vidi upravo da je exe verzija pokretana više puta, a u gornjem delu se pregledaju izveštaji.

Ispod linije menija se nalazi skup sa dostupnim izveštajima, klikom na neki od njih, taj izveštaj se može pregledati.

Po default-u je na početku prikazan uopšteni prikaz rezultata – sa listom poziva CUDA funkcija i kernela, kao i tačnim vremenskim trenucima u kojima je poziv započeo i koliko je trajalo izvršavanje.

Summary table prikazuje slične podatke, s tim što se ovde jasno vidi koliko je u procentima trajalo izvršavanje pojedinih CUDA funkcija.

Iz ove tabele je jasno da najduže traje izvršavanje kernel funkcije, što je i logično i tako treba da bude – znači da je dobro izvršena manipulacija memorijom.
Kernel table prikazuje sve pozivane kernel funkcije, kao i dimenzije blokova i mreže blokova definisane pri pozivanju kernela, korišćenu deljivu i registarsku memoriju.

Memcpy table prikazuje sve operacije transfera memorije sa host sistema na device i obrnuto. Ovakvih operacija treba da bude što manje, pošto su one veoma “skupe” – potrebno je mnogo vremena za njihovo izvršavanje.

Ukoliko je potrebno kreirati neki izveštaj o radu CUDA programa, slikovitije je predstaviti prethodno navedene podatke nekim vidom dijagrama, umesto “suvoparnih” tabela. Zato su tu npr. GPU Time Height Plot

GPU Time Summary Plot

Najnoviji CUDA softver (verzija 4.0) je naravno poboljšan u odnosu na prethodne verzije, a između ostalog nudi i neke nove mogućnosti kada je u pitanju analiza efikasnosti i performansi programa. Tako je u okviru Visual Profiler-a 4.0 moguće za svaku kernel funkciju otvoriti poseban prozor u kome se vidi mnogo detaljniji spisak podataka vezanih za poziv funkcije i optimalnost i efikasnost izvršavanja. Ja ovde neću detaljno objašnjavati šta svi ti podaci znače, ali se sva potrebna objašnjenja mogu pronaći u User Guide-u i već pomenutom Best Practices Guide-u.
Za konkretan primer koji je razmatran u ovom blogu, dodatni izveštaj o kernel funkciji izgleda ovako:

…
Kada se paralelizuje neki postojeći softver ili kada se piše novi CUDA program, uvek se treba zapitati da li postoji neki deo programa koji bi mogao bolje da se uradi ili da li postoji još neka tehnika optimizacije koja nije primenjena. U takvim slučajevima, iskustvo svakako pomaže da se lakše i brže napiše efikasnija verzija paralelizovanog softvera. Ali, bez obzira na iskustvo, treba proveriti efikasnost rada programa primenom alata koje je kompanija NVIDIA razvila sa ciljem da pomogne programerima da maksimalno iskoriste mogućnosti svojih GPU uređaja. U ovom blogu sam prikazala rad Visual Profiler alata koji omogućava analizu efikasnosti rada i na jednom jednostavnom primeru prikazala šta se sve može analizirati. Za svaki konkretan slučaj, razlikuju se segmenti na koje treba posebno obratiti pažnju. Meni je ovim tekstom bio cilj da čitaocima približim način korišćenja ovog alata, a svi oni koji budu razvijali CUDA programe će na osnovu ovog teksta moći da započnu analizu, dodatne informacije mogu naći u dokumentaciji i vremenom će steći iskustvo, tako da će od početka pisati optimizovane paralelne verzije koje će raditi drastično brže od klasičnih verzija.
Do skorog čitanja, T.Đ.
Komentari će biti prikazani pošto ih odobri moderator sajta. Da bi komentari bili objavljeni, moraju biti u skladu sa politikom objavljivanja.