Innhold
- Hvordan måle kodeutførelsestid eksperimentelt
- 1. Kjenn prosessorkraften og minnestørrelsen til mikrokontrolleren din
- 2. Valg av variabler for optimalisering i kodestørrelse
- 3. Valg av variabler for optimalisering i kodeutførelsestid
- 4. Optimalisering av aritmetiske operasjoner
- 5. Bruk en DSP-kompatibel mikrokontroller for intensive beregninger
- Instruksjoner som en DSP-prosessor kan utføre raskere enn en ALU er:
- Å bruke DSP-motoren til en mikrokontroller krever at:
- 6. Arbeid med avbrudd
- 7. Bruk de beste tilgjengelige kompilatorene
- 8. Bruk betingede uttalelser på en intelligent måte
- 9. Bruk innebygde funksjoner
- 10. Bruk dekrementerte sløyfer
- Innpakning
Forfatteren fullførte sitt siste års ingeniørprosjekt med dsPic mikrokontrollere, og fikk omfattende innsikt i disse enhetene.
En mikrokontrollers C-språkkode kan kreve optimalisering i visse avanserte applikasjoner. Denne kodeoptimaliseringen praktiseres for å redusere to viktige ting:
- Kodestørrelse: Microcontrollers kan lagre begrensede data og instruksjoner på grunn av den begrensede størrelsen på RAM. Derfor må koden optimaliseres, slik at tilgjengelig instruksjon og dataminne kan brukes på den mest effektive måten.
- Kodeutførelsestider: Mikrokontrollere er sekvensielle enheter som utfører en instruksjon om gangen. Hver monteringsinstruksjon bruker et visst antall klokkesykluser for å utføre seg selv. Derfor må koden optimaliseres for å sikre at den utfører den nødvendige oppgaven i minst antall klokkesykluser eller monteringsinstruksjoner. Jo mindre klokkesykluser en kode bruker, jo raskere går den. Dette betyr at applikasjoner kan kjøre raskere fordi behandlingstider minimeres.
Denne artikkelen presenterer tips og triks som kan brukes til å redusere størrelsen og utførelsestiden til en mikrokontrollerkode.
Microchips MplabX-utviklings-IDE vil bli brukt til å demonstrere eksempler der det er hensiktsmessig.
Hvordan måle kodeutførelsestid eksperimentelt
For å få en ide om hvor lang tid koden din faktisk tar å utføre i sanntid, må du måle den eksperimentelt. En logisk analysator kan enkelt brukes til å måle kodeutførelsestid, og de som er interessert kan spørre om prosessen for dette fra meg på e-post. Ved siden av dette:
- Noen kompilatorer har muligheten til å telle klokkesykluser en kode vil forbruke.
- Noen feilsøkere, for eksempel ICD 3 fra mikrochip, kan direkte måle utførelsestiden gjennom et stoppeklokke.
1. Kjenn prosessorkraften og minnestørrelsen til mikrokontrolleren din
Det er ikke alltid klokkefrekvensen (MHz) som gir det virkelige bildet av behandlingshastigheten til en mikrokontroller, et mer realistisk mål er MIPS (megainstruksjoner per sekund) eller antall instruksjoner MCU kan utføre i løpet av et sekund.
MCU-er varierer vanligvis fra 60–70 MIPS i high-end-kategorien til 20 MIPS 8-bit AVR-er. En høy MIPS mikrokontroller er sannsynligvis dyrere enn en low-end enhet, så her har du en avveining mellom pris og prosesseringshastighet.
Mikrocontrollere har separat minne for lagring av data og programkode. Størrelsen på dem begge finner du i databladet. Du kan trenge en MCU med større minnestørrelse hvis koden din er betydelig stor.
2. Valg av variabler for optimalisering i kodestørrelse
Mikrocontrollere har begrenset dataminne, vanligvis fra 1 til 4 kbyte. I dette tilfellet er det lurt å velge den mest passende variabeltypen i henhold til forventet område for datoen som lagres. Tabellen nedenfor oppsummerer disse variablene:
Variabel type | Størrelse i byte | Område |
---|---|---|
bool | 1 | Bare 0 eller 1 |
røye | 1 | -128 til 127 |
int | 2 | -32 768 til 32 767 |
usignert int | 2 | 0 til 65.535 |
lang | 4 | -2,147,483,648 til 2,147,483,647 |
flyte | 4 | Presis opptil 6 desimaler |
dobbelt | 8 | Presis opptil 15 desimaler |
lang dobbel | 10 | Nøyaktig opptil 19 desimaler |
Eksempel:
- Hvis to variabler X og Y skal legges til, og resultatet skal lagres i Z, men verdien av Z forventes å være høyere enn 65.535 etter tilsetning, kan Z erklæres som lang og X og Y kan erklæres som usignert int forventes det heller ikke at verdiene X og Y går negativt. Dette vil lagre 04 byte i dataminnet som ellers ville blitt brukt hvis alle variablene skulle deklareres så lenge.
- To variabler X og Y, hvis verdier forventes å være i hele tall, skal deles, men resultatet av divisjon kan gi en desimal, så kan X og Y deklareres int og resultatet kan erklæres flyt eller dobbelt, avhengig av presisjonen som kreves.
Valg av datatype kan være avgjørende når du erklærer matriser som inneholder et stort antall elementer.
3. Valg av variabler for optimalisering i kodeutførelsestid
- Det er et fastslått faktum at flytende punktberegninger tar lengre tid enn faste punktberegninger. Ikke bruk en variabel med flytende punkt der en desimalverdi ikke er nødvendig. Arbeid med usignerte heltall der det er mulig.
- Lokale variabler foretrekkes fremfor globale variabler. Hvis en variabel bare brukes i en funksjon, må den erklæres i den funksjonen fordi tilgang til globale variabler er tregere enn lokale variabler.
- En 8-biters MCU vil finne en enkelt byte-størrelse variabel raskere å få tilgang til, og en 16-biters MCU vil finne en 2-byte-variabel som er lettere å få tilgang på grunn av lengden på den genererte adressen.
4. Optimalisering av aritmetiske operasjoner
Aritmetiske operasjoner kan optimaliseres på følgende måter.
- Bruk oppslagstabeller med forhåndsberegnede verdier i stedet for å evaluere en sinus eller andre trigonometriske funksjoner eller andre operasjoner hvis resultat kan være kjent på forhånd i koden.
- Hvis en sinusoppslagstabell allerede er lagret i minnet, kan en cosinus evalueres ved å fremme matrisepekeren tilsvarende 90 grader.
- Blant de fire aritmetiske operasjonene tar deling og multiplikasjon mest behandlingstid, i praksis kan det være i hundrevis av mikrosekunder eller så i tilfelle flytende punktverdier.
- Bruk bit shift instruksjoner i stedet for deling og multiplikasjon. En høyre skiftinstruksjon 3 tjener til å dele med 23 hvor som en venstreskiftinstruksjon 1 vil tjene til å multiplisere med 21.
5. Bruk en DSP-kompatibel mikrokontroller for intensive beregninger
Noen mikrokontroller har en DSP-prosessorenhet, andre enn den konvensjonelle ALU innebygd i arkitekturen. Denne DSP-motoren er innrettet for å utføre aritmetiske beregninger veldig raskt i det minste antall klokkesykluser (en i de fleste tilfeller) mange ganger raskere enn ALU.
Instruksjoner som en DSP-prosessor kan utføre raskere enn en ALU er:
- Instruksjoner for bitskift og rotering.
- Multiplikasjoner, divisjoner og andre regneoperasjoner.
- Evaluering av Sines og andre trigonometriske funksjoner.
- Alle DSP-operasjoner som FFT, DFT, konvolusjon og FIR-filtrering.
Å bruke DSP-motoren til en mikrokontroller krever at:
- Separate DSP-biblioteker er innlemmet i prosjektet.
- Navnene på funksjonene er forskjellige fra standard mattebibliotek på C-språk. Dokumentasjon av disse bibliotekene og funksjonene kan benyttes fra det respektive produsentens nettsted.
- DSP-motoren bruker en annen variabel type 'brøk'. Lær hvordan du bruker variabeltypevariabler før du fortsetter med dsp-biblioteksfunksjoner.
Merk at standard matematikkbiblioteksfunksjoner ikke vil påkalle DSP-motoren fordi de blir oversatt til ALU-monteringsinstruksjoner.
6. Arbeid med avbrudd
Bruk avbrudd for å utføre spesifikke funksjoner som:
- Lese ADC-verdier.
- Sende og motta fra UART.
- Oppdatering av PWM-driftssyklusregistre.
- CAN- eller I2C-kommunikasjon.
Interrupt vil betjene disse funksjonene raskt sammenlignet med å utføre dem i hoveddelen ved hjelp av en funksjonsanrop eller inline-kode.
Avbrudd vil også utløse bare når det er nødvendig, mens hvis kodet i hoveddelen, vil koden utføres i hver iterasjon av mens (1) sløyfen.
7. Bruk de beste tilgjengelige kompilatorene
Kompilatorer kan automatisk implementere noen av optimaliseringene som er diskutert ovenfor mens de oversetter koden fra C-språk til monteringsspråk hvis de er riktig konfigurert. Se etter optimaliseringsalternativer i kompilatoren din, og oppgrader om mulig til profesjonelle versjoner av kompilatorer fordi de er kraftigere kodeoptimerer.
8. Bruk betingede uttalelser på en intelligent måte
- Når du bruker en rekke if-else utsagn, hold den mest sannsynlige tilstanden først. På denne måten trenger ikke MCU å skanne gjennom alle forholdene etter at den har funnet den virkelige tilstanden.
- En switch-case uttalelse er vanligvis raskere enn en if-else.
- Bruk nestede if-else-setninger i stedet for en rekke uttalelser. En if-else-blokk med mange utsagn kan deles inn i mindre undergrener for å optimalisere for verste fall (siste) tilstand.
9. Bruk innebygde funksjoner
Funksjoner som bare skal brukes én gang i koden, kan erklæres som statiske. Dette vil gjøre at kompilatoren optimaliserer den funksjonen til en inline-funksjon, og derfor blir ingen monteringskode oversatt for funksjonsanropet.
- En funksjon kan deklareres innebygd ved å bruke nøkkelordet 'statisk' sammen med den.
10. Bruk dekrementerte sløyfer
En redusert sløyfe vil generere mindre samlingskode sammenlignet med en inkrementert sløyfe.
Det er fordi det i en økningssløyfe er nødvendig med en sammenligningsinstruksjon for å sammenligne sløyfeindeksen med maksimumsverdien i hver sløyfe for å sjekke om sløyfeindeksen når den maksimale verdien. Tvert imot i en dekrementsløyfe, er denne sammenligningen ikke nødvendig lenger fordi det reduserte resultatet av sløyfeindeksen vil sette nullflagget i SREG hvis det når null.
Gitt at sløyfen må gjentas hundre ganger, vil det å redusere en instruksjon fra sløyfen unngå at den blir utført hundre ganger, slik at effekten sannsynligvis blir mer signifikant når sløyfen må gjentas mange ganger.
Innpakning
Disse tipsene kan være nyttige, men deres virkelige anvendelse og styrke avhenger av dyktigheten til programmereren og kommandoen han har på koden. Husk at størrelsen på programmet ikke alltid bestemmer utførelsestidene, noen instruksjoner kan konsumere flere klokkesykluser, så den andre, så nok en gang må ferdighetene i programmet spille sin rolle.
Denne artikkelen er nøyaktig og sann etter best forfatterens viten. Innholdet er kun for informasjons- eller underholdningsformål og erstatter ikke personlig rådgivning eller profesjonell rådgivning i forretningsmessige, økonomiske, juridiske eller tekniske forhold.