Tartalom
- Hogyan lehet kísérletileg mérni a kódfuttatási időt
- 1. Ismerje meg a mikrovezérlő feldolgozási teljesítményét és memória méretét
- 2. Változók választása az optimalizáláshoz a kódméretben
- 3. Változók kiválasztása az optimalizáláshoz a kódfuttatási időben
- 4. Számtani műveletek optimalizálása
- 5. Intenzív számításokhoz használjon DSP-képes mikrovezérlőt
- A DSP processzor gyorsabban képes végrehajtani az ALU-t, mint az alábbiak:
- A mikrokontroller DSP motorjának használatához a következőkre van szükség:
- 6. Munka megszakításokkal
- 7. Használja a rendelkezésre álló legjobb fordítókat
- 8. Használja intelligensen a feltételes kijelentéseket
- 9. Használja az Inline függvényeket
- 10. Használjon csökkentett hurokokat
- Csomagolás
A szerző befejezte utolsó évének mérnöki projektjét a dsPic mikrovezérlőkkel, és átfogó betekintést nyert ezekbe az eszközökbe.
A mikrokontroller C-nyelvű kódja bizonyos fejlett alkalmazásokban optimalizálást igényelhet. Ezt a kódoptimalizálást két kulcsfontosságú dolog csökkentésére gyakorolják:
- Kódméret: A mikrokontrollerek korlátozott adatot és utasításokat tárolhatnak, mert a RAM-ok korlátozottak. Ezért a kódot optimalizálni kell, hogy a rendelkezésre álló utasításokat és adatmemóriát a lehető leghatékonyabban tudjuk kihasználni.
- Kód végrehajtási idők: A mikrokontrollerek olyan szekvenciális eszközök, amelyek egyszerre egy utasítást hajtanak végre. Minden egyes szerelési utasítás bizonyos számú óraciklust emészt fel önmagának végrehajtásához. Ezért a kódot optimalizálni kell annak biztosítása érdekében, hogy a szükséges feladatot a lehető legkevesebb óracikluson vagy szerelési utasításon hajtsa végre. Minél kevesebb óraciklust használ egy kód, annál gyorsabban fut. Ez azt jelenti, hogy az alkalmazások gyorsabban futhatnak, mivel a feldolgozási idők minimalizálódnak.
Ez a cikk tippeket és trükköket mutat be, amelyek felhasználhatók a mikrovezérlő kód méretének és végrehajtási idejének csökkentésére.
A Microchip MplabX fejlesztői IDE-jét felhasználjuk a példák bemutatására, ahol ez megfelelő.
Hogyan lehet kísérletileg mérni a kódfuttatási időt
Ahhoz, hogy képet kapjon arról, hogy a kód valós idejű végrehajtása mennyi időt vesz igénybe, kísérletileg kell mérnie. A kódfuttatási idő mérésére kényelmesen használható egy logikai elemző, és az érdeklődők e-mailben érdeklődhetnek tőlem ennek folyamatáról. Emellett:
- Néhány fordító képes megszámolni a kód által elfogyasztott óraciklusokat.
- Néhány hibakereső, például a mikrochipről származó ICD 3, egy stopper segítségével közvetlenül mérheti a végrehajtás idejét.
1. Ismerje meg a mikrovezérlő feldolgozási teljesítményét és memória méretét
Nem mindig az órajel frekvenciája (Mhz) adja meg a valós képet a mikrovezérlő feldolgozási sebességéről, reálisabb mérőszám a MIPS (mega utasítások másodpercenként), vagy az MCU másodperc alatt végrehajtható utasítások száma.
Az MCU-k általában a csúcskategóriás kategóriában 60–70 MIPS és 20 MIPS 8 bites AVR között mozognak. A magas MIPS mikrovezérlő valószínűleg drágább, mint egy alacsony kategóriájú eszköz, így itt kompromisszumot köt a költség és a feldolgozási sebesség között.
A mikrovezérlők külön memóriával rendelkeznek az adatok és a programkód tárolásához. Mindkettőjük mérete megtalálható az adatlapon. Szüksége lehet nagyobb memória méretű MCU-ra, ha a kódja lényegesen nagy.
2. Változók választása az optimalizáláshoz a kódméretben
A mikrovezérlők korlátozott adatmemóriával rendelkeznek, általában 1–4 Kbyte-ig terjednek. Ebben az esetben célszerű a legmegfelelőbb változótípust választani a tárolt dátum várható tartományának megfelelően. Az alábbi táblázat összefoglalja ezeket a változókat:
Változó típus | Méret bájtban | Hatótávolság |
---|---|---|
bool | 1 | Csak 0 vagy 1 |
char | 1 | -128 és 127 között |
int | 2 | -32,768-32,767 |
aláíratlan int | 2 | 0–65,535 |
hosszú | 4 | -2 147 483 648 - 2 147 483 647 |
úszó | 4 | Pontos, legfeljebb 6 tizedesjegyig |
kettős | 8 | Pontos, legfeljebb 15 tizedesjegyig |
hosszú kettős | 10 | Pontos 19 tizedesjegyig |
Példa:
- Ha két X és Y változót kell hozzáadni, és az eredményt Z-ben kell tárolni, de a Z értéke várhatóan magasabb lesz, mint 65,535 az összeadás után, akkor Z hosszúnak, X és Y pedig aláíratlannak nyilvánítható int, az X és Y értékek szintén várhatóan nem negatívak. Ez 04 bájtot fog megtakarítani az adatmemóriában, amely egyébként elhasználódott volna, ha az összes változó hosszúnak lenne deklarálva.
- Két X és Y változót, amelyeknek az értéke várhatóan egész számban lesz, el kell osztani, de az osztás eredménye tizedest adhat, akkor X és Y deklarálható int-nek, az eredmény pedig lebegőnek vagy duplának mondható a szükséges pontosság.
Az adattípus megválasztása döntő lehet a nagy számú elemet tartalmazó tömbök deklarálásakor.
3. Változók kiválasztása az optimalizáláshoz a kódfuttatási időben
- Megállapított tény, hogy a lebegőpontos számítások hosszabb ideig tartanak, mint a fixpontos számítások. Ne használjon lebegőpontos változót, ha tizedesértékre nincs szükség. Dolgozzon aláíratlan egész számokkal, ahol csak lehetséges.
- A lokális változókat előnyben részesítik a globális változókkal szemben. Ha egy változót csak egy függvényben használnak, akkor azt abban a függvényben kell deklarálni, mert a globális változókhoz való hozzáférés lassabb, mint a helyi változók.
- A 8 bites MCU egyetlen bájt méretű változót talál gyorsabban, a 16 bites MCU pedig egy 2 bájtos változót könnyebben hozzáférhet a generált cím hossza miatt.
4. Számtani műveletek optimalizálása
A számtani műveletek a következő módszerekkel optimalizálhatók.
- Használjon előre kiszámított értékek felkutató táblázatait, ahelyett, hogy kiértékelné a Sine vagy bármely más trigonometrikus függvényt, vagy bármilyen más műveletet, amelynek eredménye előzetesen megismerhető a kódban.
- Abban az esetben, ha egy szinuszos keresőtábla már van tárolva a memóriában, a koszinusz értékelhető a tömbmutató 90 fokkal egyenértékű előrelépésével.
- A négy számtani művelet közül az osztás és a szorzás veszi fel a legtöbb feldolgozási időt, a gyakorlatban lebegőpontos értékek esetén akár több száz mikrosekundum tartományban lehet.
- Használjon biteltolás utasításokat osztás és szorzás helyett. A jobb oldali eltolás 3 utasítása 2-vel való osztást szolgál3 ahol bal váltásként az 1 utasítás a 2-gyel való szorzást szolgálja1.
5. Intenzív számításokhoz használjon DSP-képes mikrovezérlőt
Egyes mikrovezérlőknek van egy DSP-feldolgozó egysége, amely a hagyományos ALU-val rendelkezik, beépítve az architektúrájukba. Ez a DSP motor arra szolgál, hogy az ALU-hoz képest sokszor gyorsabban végezze el a számtani számításokat a lehető legkevesebb óraciklusban (a legtöbb esetben egyet).
A DSP processzor gyorsabban képes végrehajtani az ALU-t, mint az alábbiak:
- Biteltolás és forgatás utasítások.
- Szorzások, osztások és egyéb számtani műveletek.
- A szinuszok és más trigonometrikus függvények értékelése.
- Minden DSP művelet, például FFT, DFT, konvolúció és FIR szűrés.
A mikrokontroller DSP motorjának használatához a következőkre van szükség:
- Külön DSP könyvtárak épülnek be a projektbe.
- A függvények nevei eltérnek a C-nyelv szokásos matematikai könyvtárától. Ezeknek a könyvtáraknak és funkcióknak a dokumentációja az adott gyártó webhelyén található.
- A DSP motor más változó típusú „frakcionált”. Ismerje meg a tört típusú változók használatát, mielőtt folytatná a dsp könyvtár funkcióit.
Vegye figyelembe, hogy a szokásos matematikai könyvtárfüggvények nem hívják meg a DSP motort, mert lefordítják őket az ALU szerelési utasításaiba.
6. Munka megszakításokkal
Használjon megszakításokat bizonyos funkciók végrehajtásához, például:
- ADC értékek olvasása.
- Küldés és fogadás az UART-tól.
- A PWM munkaciklus-nyilvántartások frissítése.
- CAN vagy I2C kommunikáció.
A megszakítások ezeket a funkciókat gyorsan kiszolgálják, összehasonlítva azzal, hogy a fő törzsben végrehajtják őket egy függvényhívás vagy belső kód segítségével.
A megszakítások szintén csak szükség esetén váltanak ki, míg ha a fő törzsben kódoltuk, akkor a kód a while (1) hurok minden iterációjában végrehajtódik.
7. Használja a rendelkezésre álló legjobb fordítókat
A fordítók automatikusan megvalósíthatják a fent tárgyalt optimalizációk egy részét, miközben megfelelő módon konfigurálják a kódot a C-nyelvről az assembly nyelvre. Keresse meg az optimalizálási lehetőségeket a fordítójában, és ha lehetséges, frissítsen a fordítók professzionális verzióira, mert ezek hatékonyabb kódoptimalizálók.
8. Használja intelligensen a feltételes kijelentéseket
- Ha if-else utasítássorozatot használ, akkor először a legvalószínűbb feltételt tartja. Így az MCU-nak nem kell átvizsgálnia az összes feltételt, miután megtalálta az igazi feltételt.
- A váltási eset megadás általában gyorsabb, mint az ha más.
- Használjon beágyazott if-else utasításokat egy utasítássorozat helyett. A sok utasítást tartalmazó if-else blokk kisebb alágakra osztható a legrosszabb (utolsó) feltétel optimalizálása érdekében.
9. Használja az Inline függvényeket
A kódban csak egyszer használatos funkciókat deklarálhatjuk statikusként. Ez arra készteti a fordítót, hogy ezt a függvényt inline függvényre optimalizálja, és ezért a függvényhíváshoz nem kerül lefordításra az összeállítási kód.
- A függvény inline deklarálható, ha a „static” kulcsszót használja.
10. Használjon csökkentett hurokokat
Egy csökkentett hurok kevesebb összeszerelési kódot generál, mint egy növelt hurok.
Ugyanis egy inkrementális ciklusban összehasonlítási utasításra van szükség a hurokindex összehasonlításához az egyes ciklusok maximális értékével annak ellenőrzésére, hogy a hurokindex eléri-e a maximális értéket. Éppen ellenkezőleg, egy dekrement ciklusban erre az összehasonlításra már nincs szükség, mert a ciklus index dekrementált eredménye a nullát jelzi a SREG-ben, ha eléri a nullát.
Tekintettel arra, hogy a ciklusnak százszor kell megismétlődnie, egy hurok egy ciklusból történő csökkentésével elkerülhető, hogy százszor futtassák, így a hatás valószínűleg nagyobb lesz, ha a ciklusnak sokszor kell iterálnia.
Csomagolás
Ezek a tippek hasznosak lehetnek, de valódi alkalmazásuk és hatékonyságuk a programozó képességeitől és a kódján lévő parancstól függ. Ne feledje, hogy a program mérete nem mindig határozza meg a végrehajtás idejét, egyes utasítások több óraciklust emésztenek fel, mint a másik, ezért ismét a program képességeinek kell szerepet játszaniuk.
Ez a cikk pontos és a szerző legjobb tudása szerint hű. A tartalom csak tájékoztató vagy szórakoztató célokat szolgál, és nem helyettesíti a személyes vagy üzleti tanácsokat üzleti, pénzügyi, jogi vagy technikai kérdésekben.