Upload
others
View
2
Download
0
Embed Size (px)
Citation preview
UNIVERZITET U NOVOM SADU
TEHNIČKI FAKULTET „MIHAJLO PUPIN“
ZRENJANIN
- Seminarski rad -
- Iz predmeta: Konkurentno Programiranje-
Program za sortiranje niza brojeva korišćenjem niti
Profesor: Student:
Doc. Dr. Dejan Lacmanović Nikola Ćorković
br. Indeksa:
SI 2/15
Zrenjanin, 2017.
1
Sadržaj: 1. Uvod ....................................................................................................................................... 2
2. Razvojno okruženje ............................................................................................................... 3
3. Razvoj programa .................................................................................................................... 4
3.1 Algoritmi sortiranja .......................................................................................................... 4
4. Algoritamski prikaz programa ............................................................................................... 5
4.1. Flowchart diagram .......................................................................................................... 6
5. Struktura programa ................................................................................................................ 7
5.1. Metoda “sortAlgorithm()” .............................................................................................. 8
5.2. Metoda “sortMultiAlgorithm()”...................................................................................... 9
5.3. Main Metoda ................................................................................................................. 10
6. API funkcije ......................................................................................................................... 12
6.1. API funkcije korišćene u kodu programa ..................................................................... 12
7. Zaključak.............................................................................................................................. 13
2
1. Uvod
Program za sortiranje niza nasumično generisanih brojeva je zadatak sa vežbi predmeta
konkurentno programiranje. Zadatak je da se uz pomoć niti sortira niz brojeva, i da se izmeni
algoritam sortiranja čime se smanjuje vreme rada (sortiranja) i time ubrzava program što i jeste
cilj. Kod je pisan u CodeBlocks okruženju i sastoji se od par predefinisanih metoda i “main“
metode. Ideja za sam rad programa jeste da se niz od nasumično odabranih brojeva podeli na
manje delove i sortira svaki deo pojedinačno, te nakon toga spoji u jedan niz i sortira ponovo.
Time se dobija na vremenu tako što program lakše sortira brojeve kada je niz kraći, nakon čega
ostaje sortiranje celog niza koje je već olakšano prethodnim sortiranjem pojedinačnih delova
istog niza. Sortiranje delova niza je odrađeno uz pomoć niti čime je znatno ubrzan proces, broj
niti je proizvoljan kako i dužina niza. Svaka nit se kreira pojedinačno i u istom trenutku obavlja
prethodno definisanu metodu. Redosled nije definisan tako da je svaka nit nezavisna od ostalih,
sam tok programa mora biti regulisan funkcijom koja čeka da sve kreirane niti završe proces i
koja nakon toga dopušta nastavak. Sve ovo se odvija u vremenu manjem od 2 sekunde, sto je
značajan napredak u odnosu na 15 sekundi što je vreme istog programa koji radi na samo jednoj
niti.
3
2. Razvojno okruženje
Razvojno okruženje korišćeno za izradu jeste Code::Blocks koji je besplatano integrisano
okruženje za razvoj koda u C, C++ i Fortran programskom jeziku. Code::Blocks je i osmišljen
za izradu čak i najzahtevnijih potreba korisnika. Dizajniran je da bude veoma fleksibilan po
pitanju dodataka (ekstenzija) i da bude potpuno podesiv za sve potrebe korisnika. Integrisano
razvojno okruženje koje ima sve mogućnosti koje su korisniku potrebne, i vizualni izgled koji
je konstantan kako kroz vreme tako i kroz različite platforme radi komfornosti korisnika u svim
uslovima. Napravljen je tako da je moguće dodati bilo kakav dodatak, svaku dodatnu
funkcionalnost korisnik može ili da instalira dodatno ili sam ukuca.
Slika 1. Logo Code::Blocks razvojnog okruženja
4
3. Razvoj programa
Konačni cilj programa je da bude što brži pri sortiranju niza. Prva ideja koja je delimicno
implementirana u program jeste da se napravi niz nizova nad kojim će niti sortirati brojeve niz
po niz. Razlog tome jeste da se ubrza program. Računanje vremena izvrsavanja sortiranja se
odnosi na sam proces, sa upotrebom metoda/algoritama za sortiranje, a ne na ceo program.
Tako da bi na ovaj način bila moguća eliminacija računanja kreiranja niti, kreiranja/sortiranja
konacnog niza tako sto bi se prvo napravile sve niti, i svakoj dodeli odredjeni niz nad kojim će
vršiti sortiranje. Tako bi na primer, niz[0][20] imao 20 brojeva nad kojim jedna nit vrši
sortiranje, a sledeća nit bi već imala niz[1][20] nad kojim vrši novo sortiranje. Nakon sortiranja
svih delova niza bi se dodatnim nitima dodelili veći delovi već delimilčno sortiranog niza.
Nova nit bit dobila zadatak da vrši sortiranje nad niz [0][20], niz [1][20]…niz[x][20] gde je x
proizvoljna vrednost korisnika. I tim procesom bi se doslo do konačnog sortiranja celokupnog
niza koji je već parcijalno sortiran, i ubrzalo vreme sortiranja. Samim tim ne bi bilo potrebe za
kreiranjem niti unutar računanja vremena kao sto je u ovom primeru odrađeno jer bi se niti
kreirale u suspendovanom stanju i zatim pokrenule odmah nakon početka računanja vremena.
3.1 Algoritmi sortiranja
Algoritmi korišćeni za sortiranje su “Insertion sort“ kod „sortMultiAlgorithm()“ metode i lično
napisan algoritam kod „sortAlgorithm()“ metode. Razlog odabira ovih algoritama jeste taj da
su pokazali najbolje performanse kod testiranja programa. Algoritam koji je napisan za
„sortAlgorithm()“ funkciju je pokazivao veoma slične rezultate kao i neki algoritmi koji se
mogu naći. Samim tim ostavljen je algoritam koji je napisan od strane samog studenta. Ideja je
bila krajnje jednostavna, uzeti prvi član niza i tretirati ga kao minimum, zatim uzeti član koji
je po indeksnom broju odmah posle minimuma i ukoliko je taj drugi član manji od minimuma
zameniti im mesta. Dok je algoritam kod „sortMultiAlgorithm()“ metode implementirani
„Insertion sort“ algoritam. Koji je pri sortiranju celokupnog niza pokazivao najbolje rezultate.
Način na koji funkcioniše bolje i brže jeste taj da on prolazi samo jednom kroz niz. Zatim
podeli niz na dva niza, prvi niz je sortirani niz u koji se dodaju članovi drugog, ne sortiranog
niza. Iz drugog se uzima jedan član i prebacuje u prvi niz, zatim se uzima drugi član i stavlja
ispred ili iza prvog člana i tako dok se svi članovi iz drugog niza ne prebace u prvi niz.
Algoritam koji svi koriste pri ređanju spila karata. Uzmu se dve karte, prva je manja od druge,
tim redosledom ujedno i stoje. Zatim se uzima treća karta iz spila i stavlja na odredjeno mesto,
ukoliko je veća od obe karte stavlja se posle druge, ukoliko je manja od druge a veća od prve
ide na srednje mesto i tako dok se sve ne poređa.
5
4. Algoritamski prikaz programa
Algoritamski prikaz programa je od suštinskog značaja za izradu i razvoj softvera, razlog tome
jeste što je na taj način definisan konačan uređeni niz precizno formulisanih pravila kojima se
rešava problem, odnosno izvršava program. Svaki algoritam se, bez obzira na stepen njegove
složenosti, može predstaviti korišćenjem tri osnovne strukture:
Linijska struktura (podrazumeva izvršavanje komandi jedne za drugom)
Razgranata struktura (omogućava grananje izvršenja programa u zavisnosti od
ispunjenosti odgovarajućeg uslova.
Ciklična struktura (predstavlja niz komandi koje se mogu ponavljati više puta u
zavisnosti od ispunjenog odgovarajućeg uslova)
U slučaju kod ovog programa koji sortira brojeve ishod je moguć da bude samo jedan. Dakle
razgranata struktura se ne koristi u ovom primeru. Dok se linijska i ciklična jasno vide u
„flowchart“ dijagramu (Slika 2.). Redosled obavljanja funkcija za ovaj program i koji prati
„flowchart“ dijagram izgleda ovako:
1. START
2. Ispis: „Procesor aff:
Thread aff:
Ukupno slobodno memorije=
Ukupna velicina niza:“
3. For i=0 do BrThreads
4. niz[i]=rand()%65535
5. i++
[kraj for petlje]
6. Start Timer
7. For n=0 do BrThreads
8. CreateThread
9. sortThread()
10. n++
[kraj for petlje]
11. WaitForMultipleObjects()
12. For i=0 do BrThreads
13. CloseHandle(hThread[i])
14. i++
[kraj for petlje]
15. CreateThread
16. multiToArray()
17. CloseHandle(hThread)
18. Stop Timer
19. Ispis: „t“
20. If (iteracija<1)
21. Iteracija=1
22. For i=0 do dim
23. Ispis: („%d“,niz[i])
24. i++
[kraj for petlje]
25. END
6
4.1. Flowchart diagram
Slika 2. Flowchart dijagram programa za sortiranje niza brojeva korišćenjem niti
7
5. Struktura programa
Program za sortiranje niza brojeva je napisan u nešto više od 100 linija koda, i čine ga metode
za sortiranje i “main” metoda. Unutar main metode se prvenstveno izvršava selekciju afiniteta
procesora i niti čime se dodeljuje vrednost 255 (omogućava programu rad nad svim jezgrima
procesora i svim dostupnim, odnosno kreiranim nitima). Nakon čega se ispisuje slobodna RAM
memorija kako bi se mogao regulisati rad samog programa u dodatnom razvoju. Zatim sledi
ispis dužine niza, i deklaracija praznog niza koji se odmah u sledećem koraku kroz petlju i
“rand“ funkciju popunjava sa nasumično odabranim brojevima. Sledi deklaracija broja niti i
početak računanja vremena koje je potrebno za sortiranje niza. Kroz petlju se kreiraju niti koje
istog trenutka počinju sortiranje brojeva niza. Nakon čega se iste niti zatvaraju i pravi nova
koja sortira konačan niz, i potom zatvara. Zaustavalja se merenje vremena i ispisuje svaki stoti
član niza radi korisničke provere. Metode koje sluze za sortiranje su definisane pre same
“main” metode i to su: metoda za sortiranje određenog dela niza “sortAlgorithm()” i metoda
za sortiranje celog niza brojeva “sortMultiAlgorith()”. Obe metode se koriste kod procesa niti
i svaka ima određene parametre koji se moraju proslediti pre početka izvršavanja.
8
5.1. Metoda “sortAlgorithm()”
Metoda “sortAlgorithm()” kao što se može i videti sa slike (Slika 3.) u liniji 13 je „void“ metoda
koja nema povratnu vrednost, i koja prima dva parametra: niz[] i brojčanu vrednost dužine
niza. Zatim preko „for“ petlje uzima vrednost prvog člana niza i stavlja ga pod naziv
“min_idx”, gde zatim kroz jos jednu „for“ petlju uzima vrednost sledećeg člana i upoređuje ta
dva. Ukoliko je drugi član manji od prvog izvršava se zamena mesta prvog i drugog člana. I
tako petlje prolaze kroz ceo niz koji je metodi dodeljen. U liniji 26 je takođe metoda
„sortThread()“ koja je zadužena za samu nit. U liniji 29 se nalazi poziv prethodno objašnjene
metode, a razlog postojanja druge („sortThread()“) metode jeste taj da program pri korišćenju
više niti mora da ima kopiju nad kojom se obavlja prethodna metoda (Detaljnije o API
funkcijama pod tačkom 6, strana 12). Time se obavlja sortiranje pojedinačnih delova niza uz
pomoć više niti.
Slika 3. Isečak koda od linije 13 do linije 33 sa prikazom metoda (sortAlgorith() i
sortThread())
9
5.2. Metoda “sortMultiAlgorithm()”
Metoda “sortMultiAlgorithm()” kao što se može i videti sa slike (Slika 4.) u liniji 34 je „void“
metoda koja nema povratnu vrednost, i koja prima dva parametra: niz[] i brojčanu vrednost
dužine niza. Zatim kroz „for“ petlju uzima prvi član niza i kljuc koji je ustvari drugi član niza.
Nakon čega ulazi u „while“ petlju koja menja drugi član za prvi dokle god je prvi član veći ili
jednak nuli i dokle god je prvi član veći od drugog. Nakon čega se sve to ponavlja dok „for“
petlja ne dođe do poslednjeg člana niza. Zatim u liniji 46 se definise jos jedna metoda
(„multiToArray()“) koja kao i kod prethodnog sortiranja jednog dela koda mora da napravi
kopiju parametara nad kojima radi zadatu metodu (Detaljnije o API funkcijama pod tačkom 6,
strana 12). I ova metoda poziva prethodno objašnjenu metodu „sortMultiAlgorithm()“, linija
49, koja ustvari radi sortiranje nad celim nizom.
Slika 4. Isečak koda od linije 34 do linije 53 sa prikazom metoda (sortMultiAlgorithm() i
multiToArray())
10
5.3. Main Metoda
Pre objašnjenja same main metode potrebno je ukazati na globalne promenljive koje su
definisane na samom početku programa, linije 7, 8 i 9. Promenljiva tipa „integer“ pod nazivom
„dim“ (Slika 5.) označava dužinu niza koji je potrebno popuniti i sortirati u programu.
Promenljiva istog tipa pod nazivom „brThreads“ (Slika 5.) označava kao sto joj i ime govori
broj niti koji će se kreirati i koje će izvršavati neku funkciju. I promenljiva pod nazivom
„duzNiza“ (Slika 5.) označava dužinu niza nad kojim će jedna nit da obavlja neku funkciju.
Bitno je da množenjem dva broja koja su vrednost broja niti i dužine niza jedne niti bude jednak
broju koji je uz promenljivu „dim“, kako bi se svi brojevi celokupnog niza sortirali.
Slika 5. Isečak koda od linije 7 do linije 9, prikaz globalnih promenljivih
Main metoda počinje od linije 55 (Slika 6.) i prvo što radi jeste postavljanje afiniteta nad
jezgrima procesora i podešavanje afiniteta korišćenja niti unutar programa. Stavlja se vrednost
255 jer je to oznaka za korišćenje svih mogućih resursa (Hex: FF). Zatim se u liniji 74 definise
promenljiva t koja predstavlja promenljivu za računanje vremena. U liniji 75 je funkcija koja
generise nasumično odabran broj koja se kasnije koristi za dodeljivanje vrednosti svakog
pojedinačnog člana niza. Odmah zatim je deklarisan niz zajedno sa tipom promenljivih kojim
će isti biti popunjen i koja je njegova dužina. Nakon čega je „for“ petlja koja prolazi redom
kroz sve članove niza i svakom članu dodeljuje nasumično odabranu vrednost prethodno
definisanom funkcijom.
Slika 6. Isečak koda od linije 55 do linije 79, prikaz postavljanja afiniteta i deklaracije niza
zajedno sa popunjavanjem istog
11
Počevši od linije koda 83 pa sve do linije 101 je odrađena deklaracija niti, proces niti, sortiranje
delova niza, potom sortiranje celokupnog niza i računanje vremena izvršavanja navedenih
procesa. Prvo je deklarisan niz niti i niz prekidača koji odgovaraju niti istog indeksa u nizu.
Zatim je postavljena prmenljiva tipa „integer“ pod nazivom „n“ da ima vrednost 0. I opet
deklarisana sada samo jedna nit i jedan prekidač te niti koja/i se kasnije koristi kod sortiranja
celokupnog niza. U liniji 88 je započeto računanje vremena. Zatim je u „for“ petlji definisano
kreiranje niti sa određenom funkcijom gde je svakoj niti dodeljen određeni deo niza za
sortiranje. Nakon čega je potrebno sačekati da sve niti završe zadate funkcije i kroz jos jednu
„for“ petlju svaka nit zatvorena. U ovom trenutku program je sortirao celokupan niz isključivo
parcijalno. Ono sto sledi je definisanje i pokretanje niti koja ima funkciju sortiranja celokupnog
niza, gde se opet čega završetak sada samo te jedne niti i potom sledi zatvaranje iste i
zaustavljanje računanja vremena. Od linije 106 do 109 je odrađeno ispisivanje svakog stotog
člana niza koje služi za vizualnu proveru rada programa. Nakon čega je na samom kraju u liniji
110 oslobođena memorija koju je niz zauzimao.
Slika 7. Isečak koda od linije 81 do linije 111, prikaz korišćenja niti i ispis svakog stotog
člana niza
12
6. API funkcije
API (Aplikacioni programski interfejs) funkcije su u programiranju set podrutinskih definicija,
protokola i alata za i razvoj softvera. Dobru predstavu o tome koja je njihova funkcija opisuje
primer u kojem se govori da su API funkcije jasno definisane metode preko kojih različite
komponente jednog programa komuniciraju. Dobre API funkcije omogućavaju jednostavniji
razvoj programa, samim tim predstavljaju početne stubove koje spaja programer. API se koriste
za internet orijentisani sistem, operativni sistem, sistem baze podataka… Specifikacija API
može da bude u bilo kom obliku, uglavnom je to specifikacija koja sadrži rutine, strukture
podataka, objekte klasa, promenljive ili pozive funkcija. „Windows API“, „C++ Standard
Template Library“ i „JAVA API“ su samo primeri različitih formi API dokumentacije.
6.1. API funkcije korišćene u kodu programa
Sa slike (Slika 3.) se može videti primer jedne API funkcije koja je definisana za ovaj program
sortiranja. U liniji koda 26. se može videti da je funkcija tipa „DWORD“ (DWORD je tip
podataka koji je 32-o bitni unsigned integer) što znači da je povratna vrednost istog tipa.
Takođe se vidi da je to „WINAPI“ funkcija sto znači da više niti istovremeno mogu da je
koriste. To omogućuje stvaranje kopije za posebnu nit. Jedna nit obavlja funkciju nad nekim
podacima u datom trenutku i koristi kopije podataka nad kojima radi i kopiju funkcije koju
izvršava. Na taj način je omogućeno istovremeno izvršavanje neke funkcije između određenog
broja niti. U istoji liniji koda se vidi „LPVOID lpParam“ što ne radi ništa drugo nego ukazuje
niti adresu u memoriji koju može da zauzme za svoje potrebe. Takođe liniju ispod (linija 27.)
se vidi da je potrebno napraviti kopiju niza sa svojom adresom u memoriji radi mogućnosti
rada nad jednom promenljivom preko više niti. Zatim se vidi „while“ petlja koja je obavezna
kako bi nit znala koliko da izvršava zadatu metodu. U suprotnom bi završila sa radom
prevremena potrebnog za izvršenje metode. Pored API funkcije u liniji koda 26 postoji još
jedna API funkcija na liniji koda 46 koja je gotovo identična, sa izmenom u metodi koju
izvšava.
13
7. Zaključak
Pisanje programa koji obavlja više funkcija u jednom trenutku (prividno samo, kada ima jedan
procesor) uz pomoć više niti je veoma korisno kada je potrebno uraditi nesto u što kraćem
vremenskom periodu. Svrha korišćenja niti nije samo ubrzanje rada programa već i rad
pojedinih funkcija programa u pozadini, vizuelno nevidljivo korisniku. Što je veoma korisno
za određene stvari.