Go Down

Topic: Velocità del loop Mega 2560 (Read 10169 times) previous topic - next topic

astrobeed


A me il tuo sketch mi da meno della metà 131000 circa, allora sto arduino ha dei seri problemi!!!


Con cosa l'hai alimentato durante le feste ?
Sicuramente si è ingrassato il quarzo e adesso è in sovrapeso pertanto corre più lento  :smiley-mr-green:

pablos

#16
Jan 07, 2013, 04:44 pm Last Edit: Jan 07, 2013, 04:48 pm by pablos Reason: 1

Con cosa l'hai alimentato durante le feste ?
Sicuramente si è ingrassato il quarzo e adesso è in sovrapeso pertanto corre più lento  :smiley-mr-green:


:D :D :D

La UNO ha 16Mhz, la Mega 16Mhz i due sistemi internamente sono un po' diversi da gestire, nella 2560 ci sarà molto da fare prima di darmi il risultato o ci sono dei pelandroni  ]:D, se facciamo confronti con schede differenti, i risultati saranno diversi
no comment

qsecofr


9600 ma che importa, non la usa fino a quando l'if non è vero, tra l'altro l'attivo dopo....

Code: [Select]
void setup() {}
void loop() {
   cnt++;
   if (cnt > CNT_MAX)  {
      Serial.begin(9600);  
      Serial.println(millis() - prevMillis);
      Serial.end();
       cnt = 0;
       prevMillis = millis();
   }
}


ps .. ho provato anche con 115200 è uguale il risultato 0.495 anche  Serial.begin nel setup, cambia nulla

Può darsi che la mega debba fare più cose e quindi più lenta tu di quale MCU parli?


si  ma continui a misurare i millisecondi mentre attivi la seriale... prima fai la differenza (e la relativa chiamata a funzione millis che non si è capito quanto dura) e poi attivi quello che vuoi e stampi quello che vuoi.
Proporrei anche un ciclo molto molto più lungo...

tuxduino

Ma hai visto bene dove chiamo Serial.begin() nel mio codice e dove lo chiami nel tuo ?

lesto

io farei (in pseudocodice, sono al lavoro)

Code: [Select]

unsigned int cont = 0;
unsigned long tempoInizioMs;
setup(){
Serial.begin(9600); //mi aspetto molti meno interrupt/s dalla seriale
tempoInizioMs = millis();
}

loop(){
 cont++;
 if (!cont){ //vediamo quanto impiega a overfloodare!
    Serial.println( millis()-tempoInizioMs );
    tempoInizioMs = millis();
 }
}


ATTENZIONE: la prima lettura non è "accettabile" perchè c'è il "salto" da setup a loop, anche questo mangia cicli. Come insegna astro (un post moolto tempo fa) anche il richiamo ciclico della funzione loop mangia cicli; confrontate il risultato con questa! (il tempo mabngiato equyivale a salvare lo stato macchina nello stack etc..


Code: [Select]

unsigned int cont = 0;
unsigned long tempoInizioMs;
setup(){
Serial.begin(9600); //mi aspetto molti meno interrupt/s dalla seriale

}

loop(){
 tempoInizioMs = millis();
 while(1){
   cont++;
   if (!cont){ //vediamo quanto impiega a overfloodare!
      Serial.println( millis()-tempoInizioMs );
      tempoInizioMs = millis();
   }
 }
}

noterete anche che sempre per il motivo a richiamo funzione, l'errore del primo calcolo sarà più piccolo quì, poichè l'esecuzione di while(1){ è molto più leggera di un richiamo a funzione.
sei nuovo? non sai da dove partire? leggi qui: http://playground.arduino.cc/Italiano/Newbie

lesto

#20
Jan 07, 2013, 05:36 pm Last Edit: Jan 07, 2013, 05:38 pm by lesto Reason: 1
altro test: la mega ha molti più pin "speciali" e quindi più potenziali interrupt. provate a usare noInterrupts(): però attenzione ad attivarli per usare la seriale! quindi si fa il calcolo della millis, si riattivano l'interrupt, si stampa, si fa una serial.flush() (e una delay, la flush svuota il buffer software ma non l'hardware, è un issue che ho visto su github qualche giorno fa), si ridisattivano gli interrupt, si fa tempoInizioMs = millis(); e si ricomincia.

edit: interrupts(); per riattivare gli interrupt
sei nuovo? non sai da dove partire? leggi qui: http://playground.arduino.cc/Italiano/Newbie

qsecofr

Code: [Select]
unsigned int cont = 0;
unsigned long tempoInizioMs;
void setup(){
Serial.begin(9600); //mi aspetto molti meno interrupt/s dalla seriale
tempoInizioMs = millis();
}

void loop(){
while(1){
 cont++;
 if (!cont){ //vediamo quanto impiega a overfloodare!
    Serial.println( millis()-tempoInizioMs );
    tempoInizioMs = millis();
   };
 };
}


senza while 494-495ms di media.
con il while... mi stampa tutti 0... :smiley-eek: boo... adesso indagooo

mega 2560...

qsecofr



edit: interrupts(); per riattivare gli interrupt


emmm.... nointerrupt no timer... :smiley-mr-green:  sorry...



lesto

#23
Jan 07, 2013, 06:18 pm Last Edit: Jan 07, 2013, 06:22 pm by lesto Reason: 1
vero  :smiley-red: :smiley-red:

si può risolvere conteggiando il tempo lato pc, ed eliminando il tempo stimato per l'invio su seriale
secondi da sottrarre = (caratteri inviati * (1/baudrate) )

oppure

microsecondi da sottrarre = (caratteri inviati * (1000000/baudrate) )

Quote
con il while... mi stampa tutti 0...


uhmm che sia una ottimizzazione del compilatore? però mi pare un pò troppo aggressiva... oppure l'ovreflow avviene in meno di un milis() :) allora in quel caso prova con una micros() :)
sei nuovo? non sai da dove partire? leggi qui: http://playground.arduino.cc/Italiano/Newbie

qsecofr

rispolverando il codice iniziale (più o meno)... noto 544ms... sta mega non si muove...
Code: [Select]
const unsigned int CNT_MAX = 65000;
long cnt=0;
unsigned long prevMillis = 0;
long dif = 0;

void setup() {
    Serial.begin(9600);
}


void loop() {
    cnt++;
    if (cnt > CNT_MAX)  {
       dif = millis() - prevMillis;
        Serial.println((int) dif);
        prevMillis = millis();
        cnt = 0;
    }
}

lesto

#25
Jan 07, 2013, 06:23 pm Last Edit: Jan 07, 2013, 06:25 pm by lesto Reason: 1
vedi sopra, la unsigned int è solo di 65535, quindi o la trasformi in long oppure passiamo ad usare la micros()

edit:
Quote
sta mega non si muove...


uhm qualche altra mega di confronto? sarebbe un bel problema se le mega avesserouna pesante perdita di prestazioni da qualche parte
sei nuovo? non sai da dove partire? leggi qui: http://playground.arduino.cc/Italiano/Newbie

qsecofr

Code: [Select]
unsigned int cont = 0;
unsigned long dif;
unsigned long tempoInizioMs;
void setup(){
Serial.begin(9600); //mi aspetto molti meno interrupt/s dalla seriale
tempoInizioMs = millis();
}

void loop(){
while(1){
  cont++;
 
  if (cont == 65535){ //vediamo quanto impiega a overfloodare!
    dif = millis();
    dif = dif -tempoInizioMs;
     Serial.println( dif);
     tempoInizioMs = millis();
     cont =0;
    };
  };
}


a me sto codicice da i numeri... mi stampa solo 0.... secondo me qua il compilatore me la sta mettendo sul didietro...
l'ho un po' modificato ancora il codice qua sopra... lo so è un casino: non si fanno le prove così cambiando sempre qualcosa ma non va accidenti: ho provato il logico e l'illogico...

lesto

usa micros() al posto di millis() e lascia

if (!cont){ //vediamo quanto impiega a overfloodare!

se proprio non ti fidi equvale a: (quando overflodda la variabile torna ad essere 0)

if (cont == 0){ //vediamo quanto impiega a overfloodare!
sei nuovo? non sai da dove partire? leggi qui: http://playground.arduino.cc/Italiano/Newbie

qsecofr


vedi sopra, la unsigned int è solo di 65535, quindi o la trasformi in long oppure passiamo ad usare la micros()

edit:
Quote
sta mega non si muove...


uhm qualche altra mega di confronto? sarebbe un bel problema se le mega avesserouna pesante perdita di prestazioni da qualche parte


ma no... quanti timer ha da gestire la uno? 3 ?
il mega? 6... il nostro ciclo impiega veramente pochi cicli di clock... ma i timer vanno tenuti aggiornati comunque...
c'è un modo per disattivarli (tranne il timer 0) ?

qsecofr

#29
Jan 07, 2013, 06:56 pm Last Edit: Jan 07, 2013, 07:04 pm by qsecofr Reason: 1

usa micros() al posto di millis() e lascia

if (!cont){ //vediamo quanto impiega a overfloodare!

se proprio non ti fidi equvale a: (quando overflodda la variabile torna ad essere 0)

if (cont == 0){ //vediamo quanto impiega a overfloodare!


no no tranquillo che mi fido... tant'è che il primo test sul loop l'ho fatto con il !cont... solo che sai... quando non sai dove sbattere la testa le provi tutte... ed infatti con questa logica random ho provato a cambiare anche piattaforma: leonardo...


Code: [Select]
unsigned int cont = 0;
unsigned long dif;
int somma = 1;
unsigned long tempoInizioMs;
void setup(){
Serial.begin(9600); //mi aspetto molti meno interrupt/s dalla seriale
tempoInizioMs = micros();
}

void loop(){
while(1){
 cont=cont +somma;


 
 if (!cont){ //vediamo quanto impiega a overfloodare!
   dif = micros();
   dif = dif -tempoInizioMs;
    Serial.println( dif);
    tempoInizioMs = micros();
    cont =0;
   };
 };
}


29070MICROsecondi... quindi 29.... leonardo ha 4 timer se non vado errato...
nota che ho cambiato il cont++.... ho tentato di imbrogliare il compilatore perchè con il cont++ lo stesso programma mi fa uscire 4microsecondi...

In conclusione imho la velocità del ciclo loop "semivuoto" è dettata dal numero di interrupt (...leggasi quindi timers) che l'arduino ha attaccato... questo perchè in se il loop è tradotto con poche istruzioni assembler abbastanza ottimizzate (...all'inizio dicevo 10-15 cicli di clock perchè penso che un incremento, un salto ed un test su long grossomodo quello impieghino) però il processore è ugualmente gravato dall'aggiornamento dei timers ed eventualmente di altri interrupt esterni.

la curiosità è che questo compilatore non smette mai di stupirmi... vedi ottimizzazione che lui si è fatto sul ciclo while(1) senza che nessuno gli dica nulla..



Code: [Select]
unsigned int cont = 0;
unsigned long dif;
int somma = 1;
unsigned long tempoInizioMs;
void setup(){
Serial.begin(9600); //mi aspetto molti meno interrupt/s dalla seriale
tempoInizioMs = micros();
}

void loop(){
// while(1){
  cont=cont +somma;


 
  if (!cont){ //vediamo quanto impiega a overfloodare!
    dif = micros();
    dif = dif -tempoInizioMs;
     Serial.println( dif);
     tempoInizioMs = micros();
     cont =0;
    };
// };
}


completo... poi lascio e vado a mangiare.... 120.000 microsecondi il ciclo senza il while con il solo loop... e la differenza è veramente tanta... ma in teoria dovrebbe essere solo una chiamata ad una funzione quindi.... pochi cicli di clock... imho c'è qualcosa ancora sotto... da 29 a 120ms non vi sembra strano?



Go Up