tiistai 29. kesäkuuta 2010

Lisää työkaluja C-koodina.


13.09.2011: HepHep!
Sorsat saatavilla svn reposta
http://xp-dev.com/svn/MazBotV4/trunk/
(generic/src kansiosta)

Kappas vain miten aika rientää. Edellisestä raapustelusta onkin mennyt jo tovi, mutta lohdutukseksi voin sanoa etten ole unohtanut kumpaakaan teistä rakkaista lukijoistani. :p

No nyt sitten tuli taas mieleen, että voisin jakaa noita räpellyksiäni myös muiden harmiksi. Tälläkertaa tiputetaan ilmoille muistin säästämiseksi tehdyt bittivektori ja pakattu taulukko.

Bittivektori:

Bittivektorilla tarkoitan tässäyhteydessä simppeliä tapaa säästää muistia. Oletetaan että meillä on liuta asioita, joilla on kaksi tilaa. Vaikkapa kouluaiheisena esimerkkinä oppilaiden koetulokset. Jokainen koe voi olla joko suoritettu tai suorittamatta. Ja koska nykypäivänä kaikki koetetaan sulloa samaan purkkiin, on oppilaita hirmuinen joukko.

Oletetaan nyt että olet tekemässä ohjelmaa, joka pitää kirjaa oppilaiden kokeiden suorittamisesta. Nopein mieleentuleva keino tallettaa tieto suureen taulukkoon, ja antaa oppilaille id-numero jolla taulukko voidaan indeksoida. Sovitaan nyt vaikka että oppilaita on 10000.

Ensimmäinen viritys voisi siis olla
int koe_suoritettuna[10000];
taulukko. Nyt pohditaan tovi. Kuka tietää kuinka monta bittiä int-tyypin tieto vaatii? Ei kukaan ;) Se on hieman konearkkitehtuurista riippuvaa.. Jos nyt otetaan esimerkkimasiinaksi intelin/amd:n x86 arkkitehtuuri, niin tyypillisesti int tietotyyppi vie 32 bittiä/luku. Eli yksi suorittamatta/suoritettu tieto vie siis 32 bittiä. Jos oikein asiaa ajatellaan, niin eihän tuon tiedon tallettamiseen tarvita kuin yksi bitti, joko 0(=suorittamatta) tai 1(=suoritettu). Eli jokaisen oppilaan kohdalla hukataan 31 bittiä tilaa. 10000 oppilasta => 310000 bittiä eli 38,750 tavua, eli n. 37.8 kilotavua.

No PC maailmassa tämä ei kuulosta pahalta, mutta kun vastaavat ratkaisut viedään sulautettuun ohjelmointiin, tai käsitellään vielä suurempia tietomääriä, alkaa softan muistinkulutus päästä M$:n tuotteiden tasolle...

Muistinkulutus saataisiin heti 4-kertaa pienemmäksi muuttamalla tietotyyppi chariksi. Mutta haluttaessa yhä optimaalisempaa muistinkulutusta, joudutaan rakentamaan jokin oma viritys. Tällainen on bittivektori. Bittivektorissa voidaan yksittäisiä bittejä varata tarpeellinen määrä (poislukien alignointibitit joilla ei yleensä näissä muistimäärissä ole merkitystä), ja muuttaa/lukea yksittäisen bitin arvo. Tähän tarkoitukseen koodailin bitsetin irc-bottiani varten.

Koodi löytyy bottini repositoriosta:
http://xp-dev.com/svn/MazBotV4/trunk/generic/src/
Tiedostot MbotBitset.h ja MbotBitset.c sisältävät bittivektorin. Pakattu taulukko on tiedostoissa MbotPackedArray.c ja MbotPackedArray.h

HUOM! Tämä bitsettiviritys ei ole koeponnistettu 64-bittisillä koneilla, enkä takaa sen toimivuutta moisessa ympäristössä. Mikäli kokeilet sitä 64-bittisellä arkkitehtuurilla, niin olethan ystävällinen ja raportoit tulokset vaikka kommentoimalla tätä blogia!

Pakattu taulukko:

No jos nyt jatketaan edellistä esimerkkiä kokeen suorittamisesta, niin phditaanpa hieman vnhanmallin yliopistoarvosanojen tallennusta. Eli kokeen suorittamisesta seuraa numero, ja numero tulee tietysti myös tallentaa. Numero voi kuitenkin olla muutakin kuin 1 tai 0. Wanhaan hyvään aikaan yliopistoissa arvosanat olivat hylätty, 1,2 tai 3.
Eli nyt yhden arvosanan esittämiseen tarvitaan kaksi bittiä.
(00) = hylätty
(01) = 1
(10) = 2
(11) = 3

Tällaiseen tarkoitukseen rakentelin bitsetin kaveriksi pakatun taulukon, joka kysyy suurimman mahdollisen tallennettavan luvun, ja laskee sen jälkeen tarvittavien bittien määrän && varaa muistin ja indeksoi sen sisäisesti oikean kokoisiin palasiin. Tämän jälkeen pakatusta taulukosta/taulukkoon voi lukea/kirjoittaa arvon halutulle oppilas-id:lle.

Pakattu taulukko löytyy samasta paikasta kuin bittivektori, mutta tiedostot ovat MbotPackedArray.h ja MbotPackedArray.c

Huom! pakattu taulukko on myös täysin testaamatta 64-bittisellä alustalla (ja oletuksena on ettei se toimi oikein 64-bit ympäristössä). Lisäksi 32 bittinen ympäristökin on hieman heikohkosti testattu...
Joten kaikki havainnot pyydetään raportoimaan.


Oh, ja sekä bitsetistä, että pakatusta taulukosta löydetyt bugit voi kirjailla minulle osoitteeseen Mazziesaccount@gmail.com / kommenttina tänne blogiposteihin.

(MazBot projektille)

-Maz

2 kommenttia:

Maz kirjoitti...

unohtui mainita... Koodi on melko sekavan näköistä, ja makroilla höystettyä.. Syynä on se, että bitset on usein keskeisessä ja paljon käytetyssä roolissa.. Ja kaikki turha tupeksinta tekee nopeasta taulukko accessista huomattavasti houkuttelevamman.. Mikäli prosessorisi kykenee laskemaan jakolaskuja riittävän nopeasti, voit korvata joitain sekavahkoja siftauksia jakolaskulla ylläpidettävyyden vuoksi...

Maz kirjoitti...

30.07.2010
Ohops. Lipsahti tähän artikkeliin väärä termi. Eli kyseessähän EI ole bittkartta, vaan bittivektori. Toivottavasti en ehtinyt kovin laajalti viljellä väärää termistöä...