Pages: 1 [2] 3 4 ... 8   Go Down
Author Topic: Velocità del loop Mega 2560  (Read 7815 times)
0 Members and 1 Guest are viewing this topic.
Rome (Italy)
Offline Offline
Tesla Member
***
Karma: 128
Posts: 9411
"Il Vero Programmatore ha imparato il C sul K&R, qualunque altro testo è inutile e deviante."
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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
Logged

Genova
Offline Offline
Faraday Member
**
Karma: 39
Posts: 3389
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

 smiley-grin smiley-grin smiley-grin

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  smiley-twist, se facciamo confronti con schede differenti, i risultati saranno diversi
« Last Edit: January 07, 2013, 10:48:40 am by pablos » Logged

no comment

Offline Offline
Sr. Member
****
Karma: 8
Posts: 293
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

Code:
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...
Logged

Offline Offline
Edison Member
*
Karma: 26
Posts: 1339
You do some programming to solve a problem, and some to solve it in a particular language. (CC2)
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

0
Offline Offline
Shannon Member
****
Karma: 130
Posts: 10468
:(){:|:&};:
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

io farei (in pseudocodice, sono al lavoro)

Code:
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:
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.
Logged

sei nuovo? non sai da dove partire? leggi qui: http://playground.arduino.cc/Italiano/Newbie

0
Offline Offline
Shannon Member
****
Karma: 130
Posts: 10468
:(){:|:&};:
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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
« Last Edit: January 07, 2013, 11:38:27 am by lesto » Logged

sei nuovo? non sai da dove partire? leggi qui: http://playground.arduino.cc/Italiano/Newbie

Offline Offline
Sr. Member
****
Karma: 8
Posts: 293
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Code:
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...
Logged

Offline Offline
Sr. Member
****
Karma: 8
Posts: 293
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset


edit: interrupts(); per riattivare gli interrupt

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


Logged

0
Offline Offline
Shannon Member
****
Karma: 130
Posts: 10468
:(){:|:&};:
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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() smiley allora in quel caso prova con una micros() smiley
« Last Edit: January 07, 2013, 12:22:11 pm by lesto » Logged

sei nuovo? non sai da dove partire? leggi qui: http://playground.arduino.cc/Italiano/Newbie

Offline Offline
Sr. Member
****
Karma: 8
Posts: 293
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

rispolverando il codice iniziale (più o meno)... noto 544ms... sta mega non si muove...
Code:
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;
    }
}
Logged

0
Offline Offline
Shannon Member
****
Karma: 130
Posts: 10468
:(){:|:&};:
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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
« Last Edit: January 07, 2013, 12:25:02 pm by lesto » Logged

sei nuovo? non sai da dove partire? leggi qui: http://playground.arduino.cc/Italiano/Newbie

Offline Offline
Sr. Member
****
Karma: 8
Posts: 293
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Code:
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...
Logged

0
Offline Offline
Shannon Member
****
Karma: 130
Posts: 10468
:(){:|:&};:
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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!
Logged

sei nuovo? non sai da dove partire? leggi qui: http://playground.arduino.cc/Italiano/Newbie

Offline Offline
Sr. Member
****
Karma: 8
Posts: 293
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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) ?
Logged

Offline Offline
Sr. Member
****
Karma: 8
Posts: 293
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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:
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:
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?


« Last Edit: January 07, 2013, 01:04:56 pm by qsecofr » Logged

Pages: 1 [2] 3 4 ... 8   Go Up
Jump to: