Küsimus:
Kas lõpmatu silmus silmus () toimiks kiiremini?
Peter Bloomfield
2014-02-21 21:36:19 UTC
view on stackexchange narkive permalink

Tüüpilise visandi kirjutamisel loodate tavaliselt, et loop () kutsutakse korduvalt nii kaua, kuni Arduino töötab. Funktsioonist loop () sisse ja välja liikumine peab siiski tekitama väikese üldkulude.

Selle vältimiseks võite arvatavasti luua oma lõpmatu tsükli, näiteks järgmine:

  void loop () {while (true) {// do stuff ...}}  

Kas see on toimiv viis toimivuse parandamiseks? Kas see tekitab muid probleeme, kui loop () ei naase kunagi?

Kaks vastused:
#1
+18
Cybergibbons
2014-02-21 22:43:46 UTC
view on stackexchange narkive permalink

ATmega tuuma koodiosa, mis teeb setup () ja loop (), on järgmine:

  #include <Arduino.h>int main (void) {init (); # kui defineeritud (USBCON) USBDevice.attach (); # endif setup (); for (;;) {silmus (); if (serialEventRun) serialEventRun (); } return 0;}  

Päris lihtne, kuid seal on serialEventRun (); seal.

Võrdleme kahte lihtsat visandit:

  void setup () {} volatile uint8_t x; void loop () {x = 1;}  

and

  void setup () {} volatile uint8_t x; void loop () {while (true) {x = 1; }}  

X ja volatiil on lihtsalt selleks, et tagada, et seda pole optimeeritud.

Toodud ASM-is saate erinevaid tulemusi: Comparison of two

Näete, kui (true) sooritab rjmp (suhteline hüpe) mõne juhise tagasi, loop () aga lahutab, võrdleb ja kutsub. See on 4 juhist vs 1 juhis.

Ülaltoodud ASM-i loomiseks peate kasutama tööriista nimega avr-objdump. See on lisatud avr-gcc-ga. Asukoht varieerub sõltuvalt operatsioonisüsteemist, nii et seda on kõige lihtsam otsida nime järgi.

avr-objdump võib töötada .hex-failides, kuid nendel puudub algallikas ja kommentaarid. Kui olete just koodi ehitanud, on teil .elf-fail, mis neid andmeid sisaldab. Jällegi varieerub nende failide asukoht operatsioonisüsteemiti - lihtsaim viis nende leidmiseks on sisse lülitada häälestus kompileerimine eelistustes ja vaadata, kuhu väljundfailid salvestatakse.

Käivitage käsk järgmiselt: p>

avr-objdump -S output.elf> asm.txt

Ja uurige väljundit tekstiredaktoris.

OK, kuid kas ei ole põhjust serialEventRun () -funktsiooni kutsumiseks? Milleks see on mõeldud?
See on osa funktsionaalsusest, mida kasutab HardwareSerial, pole kindel, miks seda välja ei võeta, kui seeriat pole vaja.
Kasulik oleks lühidalt selgitada, kuidas lõite ASM-i väljundi, et inimesed saaksid ennast kontrollida.
@Cybergibbons seda ei võeta kunagi välja, kuna see on osa Arduino IDE kasutatavast standardsest `main.c`-st. Kuid see ei tähenda, et HardwareSerial teek oleks teie visandisse lisatud; tegelikult pole see kaasas, kui te seda ei kasuta (seetõttu on funktsioonis "main ()" funktsioon "if (serialEventRun)". Kui te ei kasuta HardwareSerial teeki, on "serialEventRun" null, seega ei helistata .
Kuid riistvara seeria teek on tõenäoliselt kaasatud (kas keegi saab seda kinnitada?), Kui kasutate mõnda arduino funktsiooni, näiteks "Serial.print ()". Mis võib selles olukorras juhtuda, kui teie `loop ()` silmus igaveseks ja seega ei kutsu kunagi `serialEventRun ()`? Kardan, et Serial ei pruugi sel juhul töötada.
Jah, see on osa main.c-st, nagu tsiteeritud, kuid eeldaksin, et see optimeeritakse, kui seda pole vaja, seega arvan, et Seriali aspektid on alati lisatud. Ma kirjutan sageli koodi, mis ei tule kunagi tagasi silmusest () ega märka Serialiga probleeme.
@Cybergibbons, `serialEventRun ()` kutsub erinevate jadaportide jaoks `serialEvent ()`. Vaikimisi on kõik need [tühjad protseduurid] (https://github.com/arduino/Arduino/blob/master/hardware/arduino/cores/arduino/HardwareSerial.cpp), kuid kasutaja saab need [alistada] ] (http://arduino.cc/en/Tutorial/SerialEvent), et soovi korral midagi kasulikku teha. Kui te ei alista seda, pole vaja seda helistada.
#2
+6
asheeshr
2014-02-22 14:11:34 UTC
view on stackexchange narkive permalink

Cybergibbonsi vastus kirjeldab üsna hästi koostekoodide genereerimist ja nende kahe tehnika erinevusi. See on mõeldud täiendavaks vastuseks, milles vaadeldakse teemat praktiliste erinevuste osas, st kui palju erinevust kumbki lähenemisviis teostusaja osas p>


Koodivariatsioonid

Tegin analüüsi, mis hõlmas järgmisi variatsioone:

  • Basic void loop ( ) (mis kompileerimisel muutub joondatuks)
  • Sisestamata void loop () (kasutades __attribute__ ((noinline)) )
  • Loop while (1) -ga (mis optimeeritakse)
  • Loop optimeerimata while (1) -ga (lisades __asm__ __volatile __ (""); . See on käsk nop , mis takistab silmuse optimeerimist, saamata muutuja volatile lisakulusid)
  • joonistamata void loop () optimeeritud while(1)
  • joonistamata void loop () optimeerimata while(1)

Visandid võivad olla nimega d siin.

Katse

Käivitasin neid visandeid 30 sekundit, kogudes seeläbi 300 andmepunkti. Igas silmus oli 100 millisekundiline delay kõne (ilma selleta juhtub halbu asju).

Tulemused

Seejärel arvutasin välja iga tsükli keskmised täitmisajad, lahutasin neist 100 millisekundit ja joonistasin siis tulemused.

http://raw2.github.com/AsheeshR/Arduino-Loop-Analysis/master/Figures/timeplot.png

Järeldus

  • Optimeerimata silmus while (1) void loop -is on kiirem kui kompilaatori optimeeritud void loop .
  • Ajavahe optimeerimata koodi ja Arduino vaikimisi optimeeritud koodi vahel on tähtsusetu praktiliselt . Teil on parem kompileerida käsitsi käsuga avr-gcc ja kasutada oma optimeerimislippe, mitte sõltuda Arduino IDE-st, et teid aidata (kui vajate mikrosekundilisi optimeerimisi).

MÄRKUS: tegelikud ajaväärtused pole siin olulised, erinevus nende vahel on. ~ 90 mikrosekundit täitmisaega sisaldab kõne Serial.println , micros ja delay.

MÄRKUS2: Selleks kasutati Arduino IDE-d ja selle pakutavaid vaikekompilaatori lippe.

MÄRKUS3: tugev> Analüüs (graafik ja arvutused) tehti R. abil.

Hea töö. Graafikul on millisekundid mitte mikrosekundid, vaid ka suur probleem.
@Cybergibbons See on üsna ebatõenäoline, kuna kõik mõõtmised on mikrosekundites ja ma pole kuskil skaalat muutnud :)


See küsimus ja vastus tõlgiti automaatselt inglise keelest.Algne sisu on saadaval stackexchange-is, mida täname cc by-sa 3.0-litsentsi eest, mille all seda levitatakse.
Loading...