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

qsecofr ma che arduino hai?

 cli();                // disable global interrupts
 sei();                // enable interrupts

ma come si fa ad abilitarne o disabilitarne 1 o 2 soltanon non lo so....
« Last Edit: January 07, 2013, 02:56:57 pm by pablos » Logged

no comment

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

qsecofr ma che arduino hai?

 cli();                // disable global interrupts
 sei();                // enable interrupts

ma come si fa ad abilitarne o disabilitarne 1 o 2 soltanon non lo so....

un mega ed un leonardo: scritto sotto i precedenti messaggi... però capisco: ho fatto un gran casino co 'sti test...
Logged

Genova
Offline Offline
Faraday Member
**
Karma: 43
Posts: 3486
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
ho fatto un gran casino co 'sti test...
si infatti, gli ultimi 10 post non li ho nemmeno letti ahahahahah non ho capito cosa volete fare con gli interrupt tu e Lesto smiley-wink
Ho solo visto che la seriale sta ferma e buona, non rallenta nulla fino a quando non viene sollevato il suo interrupt, per cui credo che la stessa cosa valga per gli altri smiley)) , escudere gli interrupt secondo me non serve a niente

per quanto mi riguarda fino adesso ho notato che
una variabile dichiarata const mi da 1100 cicli in piu,
5 linee di lettura eeprom anzichè un ciclo for di 5 letture annidiate mi da altri 2000 cicli, sacrificando poca mem in più
le manipolazioni dei PORT come rinomato mi da il doppio della velocità

se poi posso escludere parti che non sono necessarie con altri test meglio ancora

Sono già contento di aver messo 6000 byte circa su una eeprom da 4096

ciao
« Last Edit: January 07, 2013, 04:30:20 pm by pablos » Logged

no comment

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

Quote
ho fatto un gran casino co 'sti test...
si infatti, gli ultimi 10 post non li ho nemmeno letti ahahahahah non ho capito cosa volete fare con gli interrupt tu e Lesto smiley-wink
Ho solo visto che la seriale sta ferma e buona, non rallenta nulla fino a quando non viene sollevato il suo interrupt, per cui credo che la stessa cosa valga per gli altri smiley))

ciao

gli interrupt si voleva disabilitarli per evitare che venissero fatti e rallentassero il ciclo... solo che gli interrupt servono per aggiornare il timer0... quello del millis... no timer0 no millis no misura...
Allora: un conto è un interrupt su un segnale di un pin... tipo quello che può accadere sulla seriale... un conto è un timer: per definizione il contatore conta conta conta e conta... probabilmente si possono disabilitare giocando sul registro di controllo: a questo punto avrei da disabilitare tutti tranne lo 0 e riabilitarli eventualmente solo per il serial... ma ho lasciato le prove anche perchè ci sono tante cose che mi disturbano mentalmente più degli interrupt che so che ci sono:
1) le ottimizzazioni di questo imprevedibile compilatore.
2) il while che va 5 volte più veloce del loop...
Logged

Global Moderator
Italy
Offline Offline
Brattain Member
*****
Karma: 336
Posts: 23149
Logic is my way
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

qsecofr ma che arduino hai?

 cli();                // disable global interrupts
 sei();                // enable interrupts

ma come si fa ad abilitarne o disabilitarne 1 o 2 soltanon non lo so....
Basta "disabilitare" i relativi flag nei corrispondenti registri TIMSKx.
Ad esempio, se si vuole disattivare l'interrupt legato all'overflow del contatore del timer 0, basta dare
Code:
cli();
TIMSK0 &= ~(1<<TOIE0);
sei(
);
Per riattivarlo
Code:
cli();
TISMK0 |= (1<<TOIE0);
sei();

Attenzione che sul timer 0 c'è agganciato delay e millis.

Se invece si vogliono disattivare tutti gli interrupt legati ad un timer, e riattivarli in seguito basta salvare lo stato del registro in una variabile tampone, impostarlo a zero e poi, in un secondo tempo, ripristinare lo stato iniziale:
Code:
cli();
byte tempTimer0 = TIMSK0;
TIMSK0 = 0;
sei();
..... codice.....
cli();
TIMSK0 = tempTimer0;
sei();
Logged


0
Online Online
Shannon Member
****
Karma: 136
Posts: 10527
:(){:|:&};:
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

grazie al buon leo, che se ci sono di mezzo i timer non lo battenessuno!
quindi un
Code:
noInterrupt(); //credo sia ""
TISMK0 |= (1<<TOIE0);
//resto del codice di esempio
interrupt();
//stampa su seriale

dovrebbe funzionare ( notare che CREDO che noInterrupt(); e interrupt(); siano degli alias di cli(); e sei(); )

Quote
2) il while che va 5 volte più veloce del loop...

è normale! se guardi cosa ci sta sotto hai questo (più o meno, molto semplificato):
Code:
int main(){
  setup();
  while(1){
    loop();
  }
}
quindi in realtà hai: comunque un while, + tempo per salvare lo stato macchina nello stack, eseguire la funzione loop, recuperare lo stato dallo stack, eseguire il loop.

una chiamata a funzione è molto lenta proprio per questo fatto di dover salvare lo stato macchina (alcuni registri, le variabili locali del chiamante e i parametri, compreso il valore di ritorno) altre info http://it.wikipedia.org/wiki/Call_stack o su un testo di architetturadei calcolatori
Logged

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

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

TimeThis.h:
Code:
#include <Arduino.h>


typedef void (*functionToTest)(void);


void timeThis(const char* testName, functionToTest f, unsigned long numIterations) {
    Serial.print("Test: ");
    Serial.print(testName);
    Serial.print(" iterations=");
    Serial.println(numIterations);
   
    unsigned long startMicros = micros();
    for (unsigned long i = 0; i < numIterations; i++) {
        (*f)();
    }
    unsigned long duration = micros() - startMicros;
   
    Serial.print("total duration (us) = ");
    Serial.println(duration);
   
    float t = (float)duration / (float)numIterations;
    Serial.print("single cycle duration (us) = ");
    Serial.println(t);
}


Utilizzo:
Code:
#include "TimeThis.h"


void nullFunc() {
}


void printCharFunc() {
    Serial.print('A');
}


const unsigned long BAUD_RATE = 9600;


void setup() {
    Serial.begin(BAUD_RATE);
   
    Serial.print("baud rate=");
    Serial.println(BAUD_RATE);
   
    timeThis("null func", nullFunc, 3000000UL);
    timeThis("print char", printCharFunc, 5000UL);
}


void loop() {
}


Esempi di risultati:
Code:
baud rate=9600
Test: null func iterations=3000000
total duration (us) = 3584228
single cycle duration (us) = 1.19
Test: print char iterations=5000
duration (us) = 5199996
single cycle duration (us) = 1040.00


baud rate=115200
Test: null func iterations=3000000
total duration (us) = 3584168
single cycle duration (us) = 1.19
Test: print char iterations=5000
duration (us) = 424996
single cycle duration (us) = 85.00
Logged

0
Online Online
Shannon Member
****
Karma: 136
Posts: 10527
:(){:|:&};:
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

puntatori a funzione... dovresti fare una funzione vuota e sottrarre il tempo per la chiamata dai valori reali
Logged

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

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

Il primo test (null func) serve proprio a misurare l'overhead del meccanismo di test.
Logged

0
Online Online
Shannon Member
****
Karma: 136
Posts: 10527
:(){:|:&};:
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

non so, se la funzione è null allora non credo avvenga il salvataggio dello stato machina e consecitivo reimpostazione, voglio dire se la funzione è null, dopo il salvataggio dello stato a cosa imposti il Program Counter? quindi vedi che già perdi passaggi per strada. Stai contatndo mezzo meccanismo di salto e l'overhead della micros() e delle operazioni. una funzione vuota dovrebbe già dare un risultato diverso.
Logged

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

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

Sì ma qual è lo scopo di tutto questo ? Ottenere una misura assoluta del tempo richiesto per l'esecuzione di una certa porzione di codice ? Per quello non c'è storia, si simula o si va di debug hardware.

Secondo me lo scopo deve essere mettere a confronto due modi di fare la stessa cosa, per valutare quale ottiene un tempo di esecuzione più breve.
La misura dell'overhead con la funzione vuota non è del tutto accurato ? Ecchissene smiley era solo per determinare di che ordine di grandezza stiamo parlando...
Logged

Genova
Offline Offline
Faraday Member
**
Karma: 43
Posts: 3486
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Sì ma qual è lo scopo di tutto questo ? Ottenere una misura assoluta del tempo richiesto per l'esecuzione di una certa porzione di codice ? Per quello non c'è storia, si simula o si va di debug hardware.

Lo scopo di tutto questo è a titolo di studio, di  curiosità.

Una cosa mi sembra chiara alla quale non avevo mai pensato ma che in effetti è ovvia:

Se carichiamo un programmino sulla 328 e lo stesso sulla 2560, possiamo notare che il 328 lo esegue alla velocità doppia e questo sarebbe irrilevante quando devo azionare un relè o un led, ma quando uso uno shield? quella velocità mi manca.
Prendiamo la ethernet shield ufficiale ... la Uno mi passa la pagina al client in metà tempo rispetto alla mega, le letture su eeprom sono più veloci dato che ci sono meno processi da fare tra una lettura e l'altra, la lettura e scrittura su sd è più veloce, tutto questo non è poco, infatti il dialogo http con la 2560 non è che mi soddisfi gran che e in parte ora capisco il perchè.

Forse commercialmente è stato più comodo condividere le stesse librerie per tutti i micro piuttosto che crearne alcune appositamente per il 2560 montando un quarzo da 20MHz
ciao
« Last Edit: January 08, 2013, 04:20:16 am by pablos » Logged

no comment

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

Se carichiamo un programmino sulla 328 e lo stesso sulla 2560, possiamo notare che il 328 lo esegue alla velocità doppia e questo sarebbe irrilevante quando devo azionare un relè o un led, ma quando uso uno shield? quella velocità mi manca.

Mi sembra una cosa assurda, una differenza di velocità tra le due schede è possibile anche se usano lo stesso clock e il core del micro è praticamente lo stesso, però sulla 2560 potrebbero gravare alcuni processi di sistema che non sono presenti sulla UNO, in tutti i casi la differenza a sfavore della 2560 deve essere minima, pochi punti percentuale e non certo il doppio.
Adesso non posso fare un test strumentale sulle due schede, però più tardi ci provo e vediamo subito come stanno realmente le cose.
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

Quote
Se carichiamo un programmino sulla 328 e lo stesso sulla 2560, possiamo notare che il 328 lo esegue alla velocità doppia

E questo da cosa lo si deduce ? Davvero un atmega2560 ha un throughput dimezzato rispetto ad un atmega328 ?
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

Quote
però sulla 2560 potrebbero gravare alcuni processi di sistema che non sono presenti sulla UNO,

Processi di sistema ? Non ho controllato ogni singolo sorgente del core, ma mi pare che la compilazione condizionale tra la UNO e la MEGA riguardi soltanto periferiche hardware presenti su un chip e non sull'altro, o sui nomi di alcune periferiche comuni.
Logged

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