C absolut cimu valtozo generalasa
Andras Tantos
andras_tantos at yahoo.com
Tue Jan 6 19:32:12 CET 2004
> Andras Tantos wrote:
> > Oszinten szolva ennek nem tudom mi az ertelme:
> >
> > #define valtozo (*((volatile unsigned char *)(x20)))
> >
> > Ez ugyanugy mukodik, mint a fenti (felteve, hogy nem gepeltem el) csak
epp
> > minden C fordito megeszi.
>
> Viszont nem biztos hogy ugyanolyan kodot general belole.
Miert nem? Konstans cim elerese. Ha ezt a fordito masnak forditja, mint a
konstans cimen levo valatozo elereset, akkor eleg vacak a fordito (SzVSz).
> >>vagy egy bitet is meg lehet adni
> >>// 20h cim 1. bitje.
> >>static bit valami @ 0x20*8+1;
> >
> > Ennek mar tobb ertelme van, de itt nem csak a definialas, hanem maga a
tipus
> > se szabvanyos.
>
> Mondtam hogy nem szabvanyos, de ha mikrokontrollerre forditasz, akkor
> altalaban fontosabb hogy gyors, hatekony legyen a kod, es ennyi
> szabvanytalansagot meg lehet engedni.
Ebben nincs vita. Ha *kell* el lehet terni a szabvanytol, foleg, ha a
hordozhatosag nem szempont. Ez igaz a felhasznalora. A
fordito/nyelv/kornyezet fejlesztoi viszont haromszor el kellene
gondolkozzanak minden nem szabvanyos megoldas beepitesen. Lasd fenti pelda:
olyan forditot irni, ami a fenti makro-val ugyanazt a kodot generalja, mint
az altalad emlitett speci, nem szabvanyos szintaxis-sal kb. ugyanakkora
melo. Ebben az esetben pedig nincs elonye a nem-szabvanyos megoldas
alkalmazasanak, tehat kerulendo - mondom meg egyszer nem felhasznalo, hanem
fordito tervezo szempontjabol.
> > Amugy egy ilyen definicio nagyon veszelyes tud lenni:
> > Mit fog erre a fordito generalni. Felthetoen kenytelen lesz olvasni a
>
> Nem veszelyes, a PIC processzornak vannak bit-kezelo utasitasai, es a PICC
> ezeket forditja a kodba. Sot! Ha egy byte valtozora megadod hogy x|=0x40,
> akkor is bit utasitas fog forditani ami beallitja a 6. bitet!
Megneztem a PIC (PIC18c) leirasat, a kovetkezo van benne:
31.4.2 Bit Manipulation
All bit manipulation instructions will first read the entire register,
operate on the selected bit and then write the result back to
(read-modify-write (R-M-W)) the specified register. The user should keep
this in mind when operating on some Special Function Registers, such as the
Port Pin Register
En is pontosan errol beszeltem: a megoldas nem altalanos, bizonyos tipusu HW
regiszterek kezelesere nem alkalmas. Akkor viszont szebb, konnyebben
karbantarthato kodot eredmenyez az, ha nem haszalod ki ezt a lehetoseget, es
minden HW regisztert sajat koddal ersz el. Es megint csak: a fordito dolga
lenne az, hogy ezeket a kodreszleteket optimalis kodda forditsa az adott
porcesszoron, pl. ha vannak, ilyen bit-utasitasokka. Egyebkent te is irod,
hogy az x|=0x40 is bit-muvelet lesz, tehat a fordito meg is teszi neked ezt
a sziveseget.
> > miatt. Viszont, hogy pontosan mi fog tortenni, az el van rejtve eloled,
es
> > nincs beleszolasod a dolgok folyasaba. En nem hasznalnam. Ez az egyik
oka
>
> Nincs elrejtve, kered hogy ASM kodba forditson, es megnezed mit csinalt
belole.
Nem errol van szo. Ugy altalaban nem szerencses, a fordito viselkedesere
biznod a program mukodeset. (pl. if ((MyPtr != NULL) && (MyPtr->MyData ==
3)) {...}). Egy verzio valtas, vagy a forditonak adott forditasi opciok
valtozasa eleg ahhoz, hogy a programod mukodokepesbol hibassa valjon. A
forraskodnak egyertelmunek kell lennie, azaz ne lehessen olyan (hibatlan)
forditot irni, ami a programodbol nem mukodo kodot general. Ebben az esetben
legfeljebb azert kellhet az ASM kodot nezned, hogy miert lett lassu/nagy a
programod es nem azert, hogy miert nem mukodik. De a fenti esetben fontosabb
az a teny, hogy a megoldas csak bizonyos tipusu regiszterek eseten mukodik
helyesen, viszont ha raszoksz a hasznalatara, egy-ket olyan helyen is
hasznalni fogod, ahol nem ervenyes a hasznalata. Ha vigyazol, akkor viszont
ket radikalisan kulonbozo szintaxist kell hasznalnod a ket kulonbozo tipusu
regsziter eleresehez. Ugyanakkor van olyan megoldas, ami (eleg) hasonlo
koddal elerhetove teszi mindket tipusu regisztert, es az altalad leirtak
alapjan jo esellyel ugyanazt a kodot eredmenyezi, mint a speci szintaxis
hasznalata.
> > annak, hogy bit-mezoket se hasznalok a HW leirasara (a masik, hogy annak
a
> > kiosztasa is a fordito belso ugye, es nem biztos, hogy olyan sorrendben
> > fogja lerakni oket, ahogy en szeretnem).
>
> Nem egeszen. Szerinted mire talaltak ki? Biztos hogy olyan sorrendben
fogja
> lerakni, mert dokumentalva van.
A bit-mezoket adat-tomoritesre (optimalis memoria-kihasznalasra) es nem HW
regiszterek SW leirasara talatak ki. Tudtommal a szabvany nem rogziti a
bitmezok kiosztasi sorrendjet (MSB first, LSB first, pl.). Ha jol tudom,
csak annyit ir le, hogy nem szabad addig uj int-et nyitni, amig a
megelozoben van hely. De talan meg ez is legalis:
struct SickBitField {
int Field1: 31;
int Field2: 31;
int Field3: 1;
int Field4: 1;
}
es ebbol a fordito ezt csinalja:
DWORD1: Field1 es Field3
DWORD2: Field2 es Field4
A konkret pelda, ahol ez elo jott (egy news-group-on): az ARM procik tudnak
mind MSB mind LSB first modban mukodni. A kerdes az volt, hogy valtozik-e a
bitmezok kiosztasa ha a forditot atkapcsolod LSB-first modrol MSB-first-re.
A konszenzus az lett, hogy ha ez szamit, akkor hibas a forraskod. Leven a
szabvany nem definialja, az a program, ami epit a kiosztas sorrendjere,
ervenytelen.
> Mikrokontrollerre teljesen mas programozasi logikat kell alkalmazni mint
> PC-re.
Ebben nincs vita.
> A PC-n a nagy progik miatt fontosabb lett a kod attekinthetosege,
> masok altali ertelmezhetosege, a feladathoz legkozelebb allo
megfogalmazasa,
> es ma mar _tobbnyire_ nem szamit az eroforras igeny.
Ezzel viszont nem ertek egyet. Minden programnal fontos az attekinthetoseg,
de ez nem lenne szabad, hogy a hatekonysag rovasara menjen.
Attekinthetoseget lehet novelni jo valtozo es fuggveny-elnevezesekkel, szep
tabulalassal, jo dokumentacioval, nagyon sok mindennel, ami nem szabad, hogy
a hatekonysagot befolyasolja. De ez messzire vezet, ebbe ne menjunk bele...
> Ellenben mikrokontrolleren, ahol szukos a ROM hely, a RAM hely is, a
> sebesseg is, maskepp kell optimalizalni.
Ez igaz, de hol van ennek koze az attekinthetoseghez? Mas algoritmust
hasznalsz, mashogy osztod el a funkciokat, stb.
> Ki kell hasznalni mindent amit
> lehet, ami specifikus a processzorra. Pl. egy pointer muvelet PIC-en igen
> hulye atlathatatlan kodot tud eloidezni az architektura hulye megoldasai
> miatt (kulon RAM/ROM tar, kulon cimzesi modokkal).
Egy altalanos pointer muvelet, lehet. De ha a fordito nem ismer fel egy
konstans-pointert es nem general jo kodot a vele torteno muveletekre, akkor
vacak a fordito.
> Ellenben a fenti BIT
> deklaracio tok egyertelmu, es tudod hogy a PIC-nek van bit-orientalt
> utasitasa -> teljesen trivialis kodot fog generalni.
Megintcsak: miert kell ehhez speci tipus? Raadasul meg a leirasban is benne
van, hogy az utasitasnak lehetnek fura mellekhatasai, ezert 'esszel' kell
alkalmazni. Pont errol beszelek: a magasszintu nyelvben nem irod le
egyertelmuen a forditonak, hogy mit szeretnel (a nem specifikalt bit-ek
kezeleset illetoen) azaz a fordito (ez esetben CPU) belatasara bizod a
dolgot. Ha viszont elorinad pontosan a teendoket, akkor a fordito is
pontosan tudna, hogy mikor *legalis* a speci CPU utasitas hasznalata, es
mikor nem.
> Vagy, pl. ha kell egy szam 0.0-10.0 kozott, akkor float tipussal tok
> kenyelmesen megoldhato, jo nagy kodot fog generalni. Erdemes elgondolkodni
> hogy inkabb byte-ot hasznalsz 0-100 kozott, es majd ha lesz szerepe a
> tizedespontnak (kijelzes, egyeb szamitasok), akkor integer muveletekkel
> megoldhato. Joval gyorsabb.
Persze, de hogy jon ez ide? Amugy meg, most te is az en szekeremet tolod:
nem bizod ra a forditora, hogy a float-jaidat fix-pontos tort-kent
ertelmezze. Kezzel szepen leirod, hogy mit szeretnel, de azt elvarod a
forditotol, hogy amit specifikaltal, azt optimalisan valositsa meg. Es itt
sem az a megoldas, hogy a fordito bevezet meg egy uj tipust, hanem az, hogy
felismeri es optimalisan valositja meg az altalad eloirt muveleteket.
> Ja, meg egy fontos dolog: PIC-en nincs ertelme sebessegre optimalizalni.
> Kodmeretre kell, minel rovidebb a kod, annal gyorsabb, mivel szinte minden
> PIC utasitas 1 ciklus alatt vegrehajtodik.
Nagyon sok esetben nem erdemes sebessegre optimalizalni. Pontosabban, a
sebessegre optimalizalas nem sokban kulonbozik a kod-meretre valo
optimalizalastol. Egy-ket olyan dolog van, amit nem csinalnak meg meretre
optimalizalas eseten, es par optimalizalast maskent hangolnak, de alapvetoen
ugyanaz a ketto. BTW: egy P-VI-esen is gyorsabb tud lenni a kisebb kod, mert
kevesebb cache-miss-t okoz, pl. Nem csak kis mikrokontrollerekre igaz, amit
irsz.
Udv,
Tantos Andras
More information about the Elektro
mailing list