maakt het wat uit?

Software die niet past in bovenstaande onderwerpen
Berichten: 4
Geregistreerd: 01 Feb 2017, 15:49

maakt het wat uit?

Berichtdoor MarcelWierda » 24 Feb 2017, 02:50

Dag ieder!,

In de Arduino IDE is de plek om variabelen te definieren anders is dan ik gewend ben van vroeger.
Met een test programma ben ik met een vraag blijven zitten. De sketch doet niets nuttigs anders dan tijd meten.

De variabelen definitie heeft 2 regels en is getest op POSITIE A, B en C (zie code), ik krijg als output met een Leonardo 16mHz:

POSITIE A bij 100.000 loops duurt een loop 48.30 uSec, bij 2 miljoen loops 24.29 maar bij 10 miljoen weer 24.92.0 uSec
POSITIE B bij 100.000 loops duurt een loop 68.32 uSec, bij 2 miljoen loops 24.81 maar bij 10 miljoen 25.02 uSec
POSITIE C bij 100.000 loops duurt een loop 41.38 uSec, bij 2 miljoen loops 14.44 en bij 10 miljoen 15.01 uSec

Nou is een micro seconde niet echt een heus probleem in een mensenleven maar toch ... hoe komen die verschillen?
C is heel anders omdat het lokale variablelen worden maar het verschil tussen A en B?
En ook het oplopen van de duur tussen 2 miljoen en 10 miljoen loops snap ik niet ... drift in de klok?

Om de 3 situaties te proberen hoef je in de code alleen de commentaar strepen te wissen / plaatsen.
output in monitor (cntr-shft-M)

Straks blijkt de code fout te zijn!
Marcel

Code: Alles selecteren
// Testware 170223a
double  Teller = 0, LoopTeller = 50000;

float   LoopDuur;           // POSITIE A
int     MijnRijtje[10],i;   // POSITIE A
 
void setup()
  {   Serial.begin(12345); while (!Serial); // com needs time ...
  }

//float   LoopDuur;           // POSITIE B
//  int     MijnRijtje[10],i; // POSITIE B
 
void loop()
{
//  float   LoopDuur;          // POSITIE C
//  int     MijnRijtje[10],i;  // POSITIE C

  for (i = 0 ; i < 10 ; i ++)  MijnRijtje[i]= i;
  Teller ++;
  if (Teller == LoopTeller)
  {
    LoopDuur = (millis() / LoopTeller) * 1000;
    LoopTeller = LoopTeller + 50000;
    Serial.print(LoopTeller,0); Serial.print(" loops, looptijd uSec/loop: ");Serial.println(LoopDuur);
  }
}

Advertisement

Gebruikers-avatar
Berichten: 2655
Geregistreerd: 06 Aug 2016, 01:03

Re: maakt het wat uit?

Berichtdoor Koepel » 24 Feb 2017, 09:23

Een digitalWrite() duurt al 5 µs.
Ik heb het geprobeerd met een Arduino Pro Micro (dat is dezelfde ATmega32U4 als de Leonardo), en na een aantal malen proberen zie ik geen verschil tussen 'A' en 'B'.

Je sketch heeft wat ruimte voor verbetering :mrgreen:
De functie millis() geeft een 'unsigned long' terug, dus alle variabelen om tijd te meten kunnen beter 'unsigned long' zijn.
Je gebruikt de waarde van millis() sinds het opstarten, maar dat varieert door while(!Serial);

Het is beter om het verschil te meten.
Code: Alles selecteren
  unsigned long t1 = millis();
  <de code om te testen>
  unsigned long t2 = millis();
  Serial.println( t2 - t1);


Een 'double' is een floating point getal. Op de Leonardo (en Uno en Mega) bestaat geen 'double', dat wordt door de compiler opgevat als een 'float'. Wanneer je daarmee berekeningen doet, dan wordt een software library gebruikt.
Je meet dus nauwelijks de tijd van de for-loop, maar vooral van de 'double' en 'float' berekeningen daar om heen.

Ik vind het zelfs dubieus om de tijd te meten van een hele kleine for-loop. Dat is een situatie waar de compiler extreem kan optimaliseren. Iedere kleine wijziging kan die optimalisatie anders maken. De Arduino is geoptimaliseerd voor de kleinst mogelijke code, niet voor de snelste code.
Je kunt je sketch voor de snelst mogelijke code zetten met dit bovenaan je sketch:
Code: Alles selecteren
#pragma GCC optimize ("Ofast")

Denk je dat die for-loop door de compiler wordt gecompileerd en uiteindelijk ook wordt uitgevoerd ? Ik ben daar nog niet zo zeker van. De compiler ziet dat het resultaat van 'MijnRijtje' niet wordt gebruikt, dus misschien wordt die for-loop overgeslagen :geek:

Berichten: 4064
Geregistreerd: 16 Okt 2013, 14:31
Woonplaats: s hertogenbosch

Re: maakt het wat uit?

Berichtdoor shooter » 24 Feb 2017, 11:40

een paar opmerkingen:
je hebt het over een loopduur, maar eigenlijk heb je het over de tijd dat het programma loopt.
verder heb je een teller in een float staan, maar dat moet eigenlijk een unsigned long zijn, (je zult merken dat het dan sneller gaat)
zoals koepel al zegt, is een floating point een berekening en niet een simpele instructie.
Beter is om de tijd de loop begint te bewaren en als de loop klaar is.
Misschien is de volgorde ook belangrijk, en ach een compiler is ook maar een mens (nou ja)
paul deelen
shooter@home.nl

Terug naar Overige Software

Wie is er online?

Gebruikers in dit forum: Geen geregistreerde gebruikers en 3 gasten