Pages: [1] 2 3 ... 8   Go Down
Author Topic: Velocità del loop Mega 2560  (Read 7837 times)
0 Members and 1 Guest are viewing this topic.
Genova
Offline Offline
Faraday Member
**
Karma: 39
Posts: 3389
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Ho voluto per curiosità vedere quanti cicli loop fa il mio arduino in un secondo con un programma a vuoto.
Possibile che su 16MHz di clock arrivo a 80Khz (80.000 cicli) ???
Dove vanno a finire tutti quei Mhz, va bene che ci sono un po' di cosette da gestire nel micro, ma secondo me è una perdita enorme di risorse.

ciao

 
« Last Edit: January 09, 2013, 05:18:25 am by pablos » Logged

no comment

Cagliari, Italy
Offline Offline
Tesla Member
***
Karma: 112
Posts: 7106
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hai provato lo speed test? --> http://playground.arduino.cc/Main/ShowInfo
Logged

Code fast. Code easy. Codebender --> http://codebender.cc/?referrer=PaoloP

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

Hai provato lo speed test? --> http://playground.arduino.cc/Main/ShowInfo
no non ho provato, a me interessa sapere quante volte mi esegue il loop

Code:
unsigned long preMillis=0;
unsigned long counter=0;

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

void loop (){

 counter++;
   if(millis() - preMillis >= 1000)
  {  
       preMillis = millis();      
       Serial.println((String)counter);
       counter=0;
  }
}
Logged

no comment

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

La curiosità è nata dal fatto che avendo una Mega con 70 pin utilizzabili, mi chiedevo se era davvero utile convertire tutti i cicli for di digital.write(x,0) e digital.read in  PORTxx |= _BV(PORTxx); e PINxx

e direi proprio di si!!  il tempo si dimezza quasi, un programma molto lungo, va ottimizzato al massimo, sapevo che era + veloce la manipolazione delle porte, ma non sapevo quanto smiley

Code:
unsigned long preMillis=0;
unsigned long counter=0;

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

void loop (){
//----------------------------------
  /* accendi il led */ //44
  //PORTL |= _BV(PORTL5);
  /* spegni il led */ //44         questo lo fa 76.123/sec
  //PORTL &= ~_BV(PORTL5);
//----------------------------------

//----------------------------------
  digitalWrite(44,1);
  digitalWrite(44,0);//            questo lo fa 38.324/sec
//----------------------------------

 counter++;
 
   if(millis() - preMillis >= 1000)
  {  
       preMillis = millis();      
       Serial.println((String)counter);
       counter=0;
  }
}
« Last Edit: January 07, 2013, 06:41:11 am by pablos » Logged

no comment

Global Moderator
Italy
Online Online
Brattain Member
*****
Karma: 328
Posts: 22738
Logic is my way
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

La lentezza della digitalWrite è rinomata. La digitalWrite esegue diversi controlli, primo fra tutti vedere se stai lavorando su un pin PWM, nel caso disattiva il corrispondente segnale ecc... Alla fine tutta 'sta roba la paghi.
Logged


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

Hai provato lo speed test? --> http://playground.arduino.cc/Main/ShowInfo
no non ho provato, a me interessa sapere quante volte mi esegue il loop

Code:
unsigned long preMillis=0;
unsigned long counter=0;

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

void loop (){

 counter++;
   if(millis() - preMillis >= 1000)
  {  
       preMillis = millis();      
       Serial.println((String)counter);
       counter=0;
  }
}

però questo programma non è esattamente scevro di operazioni... incrementa un long chiama la millis (che chissà quante operazioni fa) , sottrae due long, compara... quanto impiega una funzione millis?
la seriale poi ... presumo venga gestita ad interrupt?
Logged

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

Bhe la seriale è l'unica istruzione che impegna il micro alla fine del secondo trascorso
Logged

no comment

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

La lentezza della digitalWrite è rinomata. La digitalWrite esegue diversi controlli, primo fra tutti vedere se stai lavorando su un pin PWM, nel caso disattiva il corrispondente segnale ecc... Alla fine tutta 'sta roba la paghi.


Certo che è rinomata, ma sono quei miseri 80.000 cicli a vuoto che mi lasciano perplesso, tu stesso in qualche post non ricordo quale, hai detto che vengono impegnate librerie che non vengono usate, vabbè era un appunto nulla di grave  smiley-grin smiley-grin

ciao
Logged

no comment

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

Bhe la seriale è l'unica istruzione che impegna il micro alla fine del secondo trascorso

si quella non mi preoccupa... però sta all'ascolto sulla seriale... questo mi preoccupa di più ma non tanto...
imho il problema è il millis... e vorrei (ma ora no posso) fare un esperimento... 80000?

Code:
setup
cont = 0
oldmillis = millis


loop

cont ++
if cont > 100000
   serial print millis()-oldmillis
   oldmillis = millis
   cont =0
endif


capito cosa vorrei fare? quanti millis impiega ad incrementare una variabile e testare la stessa 100000 volte?
 vorrei quasi scommettere  che questo ciclo te lo fa in un 10-15 clock... 1 megahz... stasera provo.
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

Per curiosità ho fatto qualche esperimento:

Code:
unsigned int cnt = 0;
const unsigned int CNT_MAX = 65000;

unsigned long prevMillis = 0;


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


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


Tempo medio: 230 ms
65000 / 0,230 = 282608 chiamate di loop() al secondo


Modificando le prime due righe in:
Code:
unsigned long cnt = 0;
const unsigned long CNT_MAX = 65000;

Tempo medio: 278 ms
65000 / 0,278 = 233812 chiamate di loop() al secondo
Logged

Rome (Italy)
Offline Offline
Tesla Member
***
Karma: 129
Posts: 9441
"Il Vero Programmatore ha imparato il C sul K&R, qualunque altro testo è inutile e deviante."
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Ho voluto per curiosità vedere quanti cicli loop fa il mio arduino in un secondo con un programma a vuoto.

Il tuo non è un programma a vuoto, contiene calcoli con valori long che richiedono molti cicli macchina.
Questo è un programma quasi  a vuoto:

Code:
void setup() {
   pinMode(13, OUTPUT);     
}

void loop()
{
 PORTB = 0xff;
 PORTB = 0x00;
}

Le due scritture dirette su PORTB richiedono solo 125 ns, come evidenziato nell'immagine allegata della misura sul pin 13 con un DSO, mi è toccato fare una foto al volo della schermata perché vicino al pc ho il Tektronix per il quale non tengo installato il software per scaricare le schermate.
Come si vede la frequenza per questo loop è 1.06 MHz, il periodo necessario per la sola loop, è di 875 ns - 62.5 ns = 812.5 ns = 13 cicli macchina.
Comunque no ha molto senso parlare di massima velocità della loop visto che in realtà dipende da quello che fai al suo interno a cui devi sommare 875 ns ( ~1.43 MHz) per la sua durata reale



* loop.jpg (307.18 KB, 1024x768 - viewed 48 times.)
Logged

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

@Astro, mi rendo conto che non è proprio a vuoto, ma tu hai un oscilloscopio eheheh io non potevo farlo se non contando approsimativamente i secondi, grazie per la prova a banco (o l'avevi già fatta smiley )
é anche molto probabile che il mio millis che parte al reset è già abbastanza avanti, il valore di paragone che uso è comunque una costante dove lo stesso errore viene riportato ogni volta che aggiungo un pezzetto di prova.


Il mio programma su arduino 2560 è diventato quasi 2000 righe con un 60k circa occupati e ho notato tristemente che nel loop ci passa circa 23 volte al secondo cercavo di capire facendo piccoli pezzi alla volta quale fosse la procedura migliore per migliorarne le prestazioni

ciao
Logged

no comment

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

@tuxduino

Quote
Tempo medio: 230 ms
65000 / 0,230 = 282608 chiamate di loop() al secondo

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

ciao

Logged

no comment

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

Che velocità hai impostato per la seriale ?
Logged

Genova
Offline Offline
Faraday Member
**
Karma: 39
Posts: 3389
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?
« Last Edit: January 07, 2013, 10:39:01 am by pablos » Logged

no comment

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