Software engineering deep level optimization - uvod u merenje - III deo

Nakon što se primene određene tehnike optimizacije software-a, performanse je potrebno izmeriti kako bi bili sigurni da je optimizovanje software-a uspešno završeno. Ono u šta moramo biti sigurni je do kog nivoa tačnosti i preciznosti moramo izvršiti merenje. Već sam napomenuo da se u slučaju deep level optimizacije (asm) brzina izvršavanja meri brojanjem ciklusa takta a u ovom blog postu ću pokazati prvo i zašto. Svakako, na početku ću proći kroz koncept rada računarskog sistema sa multi-threading operativnim sistemom koji se izvršava na jednom procesorkom jezgru, radi jasne slike zašto se broje clock ciklusi a ne meri sistemsko vreme, kako to mnogi developeri rade, radi dobijanja rezultata merenja, što je daleko od bilo kakve tačnosti i preciznosti merenja. Nakon toga u narednim blog postovima prikazaću hardware-ske brojače i kako se isti koriste i zbog čega (ovde je naravno jasno, uvek dodata hardware-ska jedinica integrisana u core mikroprocesora znači da ista ne zahteva vreme procesorskog izvršavanja, jer posao obavlja samostalno, ali u isto vreme troši više električne struje, no o tome u narednim blog postovima).

Merenje sistemskim vremenom

Većina developera će posegnuti za tehnikom merenja razlike sistemskog vremena koje započinje na početku methode od mernog značaja a završava se na kraju metode, po sledećem principu, dole prikazani pseudo kod.
 
void Method(){
     StartTime // recimo da je trenutno vreme 15:00:00
     Telo metode, optimizovan source code tela metode čije izvršavanje merimo
     EndTime // vreme završavanja methode, recimo da je isto 15:01:15
     Vreme izvršavanja jednako je EndTime - StartTime 1:15
}

Developer zaključuje da je vreme izvršavanja jedan minut i petnaest sekundi, što je manje od prvobitnih loših tri minuta, te smatra da je optimizovao kod u dovoljnoj meri te da se isti brže izvršava. Ukoliko isto merenje pokrenete drugi, treći i četvrti put sigurno ćete dobiti različita vremena: 1:30, 1:25, 1:10, te možemo doći do zaključka da i niste baš sigurni koliko procenata je software optimizovan, te morate upotrebiti novu tehniku merenja kako bi ste dobili tačno i precizno merenje. Gore navedena tehnika merenja je odokativna i treba je izbegavati jer nije tačno i precizno merenje. Razlog dobijanja različitih vremena leži u konceptu izvršavanja multi-threading operativnih sistema što ću u nastavku i prikazati.

Osnove računarskog sistema

Računarski sistem je sačinjen od procesora, memorije (RAM, ROM), perifernih jedinica (koje mogu biti i zasebni računarski sistemi), sistemskog timer-a i interrupt kontrolera, ovo je osnova. Sistemski timer je jedan od osnova multi-threading operativnih sistema jer mu se zadaje vremenski okvir izvrašavanja jednog thread-a nekog od procesa operativnog sistema, te kada vremenski period istekne sistemski timer okida interrupt request visokog prioriteta koji trigeruje interrupt rutinu koja započinje preemption thread-ova na procesorkom jezgru sa nekim od drugih procesa koji čekaju na izvršavanje. Kako se zamena (preemption) thread-ova vrši brzo u vremenu, krajnji korisnik računarskog sistema ima krajnji osećaj da software radi paralelno. Sistemski timer kao i svaki drugi periferni hardware je u sprezi sa interrupt kontrolerom, pri čemu se istom prosleđuje interrupt request. Nisu sve hardwarske periferije istog prioriteta, te se neki hardware-ski zahtevi obrađuju po većem a neki po manjem prioritetu. U svakom slučaju dati koncept računarskog sitema sa multi-threading operativnim sisteom deli jezgro procesora između thread-ova različitih procesa koji se izvršavaju, te tako stvaraju privid da se software izvršava paralelno, zapravo preemption je brz i omogućava brzi switch između threadova. Ovde sada možemo nastaviti dalje, te objašnjavati da je proces skup threadova, koji se zapravo i izvršavaju na jezgru procesora te da je za svaki od njih vezan i zaseban stack, te da thread objekat sam po sebi nije jeftin objekat operativnog sistema po pitanju vremena inicijalizacije. Koncept je jasan, thread se izvršava na procesorkom jezgru dok ne istekne vremenski period dodeljen za dati thread ili dok se ne desi interrupt koji zahteva momentalno prekidanje i obradu određene rutine. Na sledećem linku možete pogledati detalje vezane za interrupt request IRQ. Prikazani koncept važi za bilo koji računarski sistem, jer svaki je i izgrađen na istom principu. Ono što je bitno jeste razumeti koncept jer razumevanje istog vodi ka tome da i razumete zašto gore navedeno merenje izvršavanja funkcije daje odokativne rezultate merenja, te nije tačno i treba ga izbegavati.
 
Provera interrupt prekida se dešava nakon završene mikroprocesorke instrukcje, sledi rutina koja proverava da li se desio neki od interrupt requestova visokog prioriteta, te ako interrupt kontroler pokaže isto sledi preemption trenutno izvršavanog thread-a na rutinu u okviru thread-a većeg prioriteta. I u ovome upravo i leži problem zašto je gore navedeno mernje problem i isključivo odokativno. Vi jednostavno niste sigurni koliko puta će kod u okviru tela methode koje merite biti zamenjeno drugim thredom većeg prioriteta te koliko će puta samim tim biti na stanju wait za izvršavanje, dok sistemsko vreme teče! Samim tim i merenja su drugačija jer jednostano nemate kontrolu nad time koliko puta sledi preemption tela metode čiju brzinu izvršavanja merite - ukoliko se threading izvršava u normalnom režimu i ne forsirate izvršavanje istog.

PCM - Hardware performance counter monitor

Merenje brzine izvršavanja programskog koda jednostavno se ne meri sistemskim vremenom, kako je to gore navedeno, već merenjem broja oscilacija takta. Isto se vrši primenom hardware-skih brojača integrisanih u mikroprocesoru ukoliko ih isti i ima integrisane. Samim tim moguće je i merenje broja  oscilacija takta isključivo dok se izvršava programski kod čije se izvršavanje meri. Na preemption thread-a performance counteri ne mere oscilacije jer nije vezan za drugi thread. Takođe potrebni su vam sistemski drajveri da bi ste omogućili i koristili hardware-ske brojače koje ćete koristiti za merenja. Pretplata na event koji procesor trigeruje omogućava hardwareskim brojačima da se inkrementiraju. U narednim blog postovima slede detalji o hardware-skim brojačima i kako ih koristiti za merenje brzine izvršavamnja koda programa. Sledeći blog post će biti orjentisan na Concurrency Visualizer za Visual Studio kako bih praktično prikazao preemtion thread-ova o kome sam pisao u ovom blog postu.


Autor:
Vladimir Savić
zilsel-invent

Comments

Popular posts from this blog

Electrolytic capacitors and design rules

Fake VC830L digital multimeter

How to design LM324 Astable Multivibrator