Pages: 1 ... 5 6 [7] 8   Go Down
Author Topic: Velocità del loop Mega 2560  (Read 8533 times)
0 Members and 1 Guest are viewing this topic.
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 quanto riguarda l'uso della RAM, è vero che i due buffer di trasmissione e ricezione vengono allocati indipendentemente dal fatto che si usi la seriale o no. Per quanto riguarda le schede basate sul 328, questo rappresenta un problema nel caso in cui il codice utilizzi quasi tutta la RAM e non faccia uso della seriale. Evitando di compilare il supporto Serial si risparmierebbero 128 byte (vedi HardwareSerial.cpp, SERIAL_BUFFER_SIZE vale 64 nei processori con più di 1000 byte di RAM, come il 328, e ci sono due ring_buffer: uno di ricezione e uno di invio).
Nel caso della Mega si hanno 4 seriali, quindi 128 x 4 = 512 byte.
In entrambi i casi si tratta del 6,25% della RAM.
In particolare, nella MEGA se uno sketch ha bisogno di molta RAM ed usa solo una seriale (ad esempio), si ritrova con 3 x 128 byte inutilmente occupati.

Per quanto riguarda il discorso prestazionale io eliminerei la funzione serialEventRun.
Non mi pare così difficile (anche per chi è neofita) interiorizzare questo costrutto:

Code:
if (Serial.available() > 0) {
    char ch = Serial.read();
    // fai qualcosa con ch
}

Visto tra l'altro che usando serialEventRun la cosa si tradurrebbe in:

Code:
void serialEvent() {
    char ch = Serial.read();
    // fai qualcosa con ch
}

Guadagno ? Nullo. La stessa cosa la potrebbe scrivere l'utente.

Nel caso della MEGA, poi, usare la tecnica esplicita ed eliminare serialEventRun significherebbe automaticamente includere solo le chiamate ad available() per le porte seriali effettivamente utilizzate.

Per quanto riguarda la ram "sprecata" nel caso di porte seriali non utilizzate, in teoria basterebbe eliminare l'istanziazione automatica degli oggetti Serial1, Serial2, ecc. ma c'è un grosso ma: gli interrupt. Bisogna legare un particolare interrupt di ricezione seriale ad una particolare istanza di Serial. Non credo ci sia un modo alternativo di farlo rispetto a com'è scritto attualmente (o almeno su due piedi non riesco ad immaginarlo).
Logged

Genova
Offline Offline
Faraday Member
**
Karma: 40
Posts: 3446
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

In ogni caso non è compito nostro ottimizzare la baracca smiley al massimo segnalarla, sempre che abbiano ancora interessi a venderla

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

Come sarebbe a dire non è compito nostro ? smiley-grin
Per togliere di mezzo il problema uno può sempre modificare la copia di main.cpp che si trova sul computer in questo mdo:

Code:
for (;;) {
loop();
//if (serialEventRun) serialEventRun();
}

et voilà, problema risolto smiley

Anzi, se hai tempo / voglia, non è che rifaresti il test di "velocità" commentando appunto quella riga là ?
(N.B.: mettere quel commento non significa disabilitare alcuna seriale, né risparmiare RAM, ma "solo" cicli macchina.)
Logged

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

Ilbhe veramente il concetto di open-source è che gli utenti contribuiscono, tra laltro github e bello proprio perche e facile inviare le proprie modifiche ovvero le pull request.

Per il codice le istanze ci sono, e solo la creazione de: buffer che è spostata. Forse ho sbagliato ad i tendere, in tal caso forse ho capito e basta un doppio puntatore è un chek del null nelle isr
Logged

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

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

La soluzione di tuxduino pare quella più logica. Basterebbe commentare quella riga, inserire delle #define aggiuntiv per attivare le seriali a richiesta e poi chiamare da dentro il setup() la configurazione delle seriali.
L'idea sarebbe quella di attivare solo le seriali che servono, evitando di accendere interrupt e relative ISR inutili nonché buffer inutilizzati.

void setup() {
//esempio: gestisco solo le prime 2 seriali
#define CREATE_SERIAL_0
#define CREATE_SERIAL_1
serialSetup();
}

Una cosa simile l'ho vista fare nella libreria PinChangeInt che ho usato recentemente.
Se non vuoi attivare la PinChangeInt sui pin di una particolare porta, metti una define prima di istanziare la libreria. Questo è un estratto del firmware del mio Micrologio:
Code:
#define NO_PORTC_PINCHANGES //indica a PinChangeInt che la porta C non sarà utilizzata per gli interrupt di cambio di stato dei pin
#define NO_PORTD_PINCHANGES //indica a PinChangeInt che la porta C non sarà utilizzata per gli interrupt di cambio di stato dei pin
#include <PinChangeInt.h> //serve per pilotare gli interrupt di cambio di stato dei pin
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

Il posizionamento delle #define prima di serialSetup è fuorviante: sembra che il contenuto di serialSetup() possa essere modificato dalla presenza o meno di quegli statement, un po' come se fossero dei parametri che passi ad una funzione.

Per come è scritta attualmente l'implementazione della seriale hardware, non è possibile influenzare la compilazione condizionale di quel codice tramite #define nel file .ino dello sketch. Se osservi attentamente l'esempio PinChangeInt, noterai che le #define sono prima di un header file.
I file .cpp vengono compilati ciascuno in modo indipendente. In altre parole le #define non si propagano tra compilation units, a meno di non includere un .h comune che potremmo chiamare "di configurazione" in cui si definiscono o non definiscono le feature che si vogliono abilitare.
Logged

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

Sì ma difatti la proposta sarebbe quella di riscrivere il modo in cui viene attivata la Seriale.
So che l'attuale HardwareSerial viene chiamata PRIMA dell'inclusione dello sketch nel main che viene generato a fine precompilazione, ecco perché bisognerebbe mettersi di fino a modificare il core.
E qui si torna a chi mi pare abbia sollevato la questione del "ne vale la pena"?
Logged


Genova
Offline Offline
Faraday Member
**
Karma: 40
Posts: 3446
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Per togliere di mezzo il problema uno può sempre modificare la copia di main.cpp che si trova sul computer in questo mdo:

Code:
for (;;) {
loop();
//if (serialEventRun) serialEventRun();
}

et voilà, problema risolto smiley

Anzi, se hai tempo / voglia, non è che rifaresti il test di "velocità" commentando appunto quella riga là ?
(N.B.: mettere quel commento non significa disabilitare alcuna seriale, né risparmiare RAM, ma "solo" cicli macchina.)

MEGA 2560:
Prendendo in esame lo sketch pag 1  Reply #9 e commentando quell'if

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

***

MEGA 2560:
escludendo le 3 linee dei vari serialEvent1/2/3 sulla HardwareSerial.h

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

***

MEGA 2560:
lasciando tutto senza modificare nessuna lib

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

Quote
bisognerebbe mettersi di fino a modificare il core.
E qui si torna a chi mi pare abbia sollevato la questione del "ne vale la pena"?
Probabilmente no, essendoci la DUE che ha lo stesso prezzo e dimensioni della Mega ma con maggiori potenzialità.
« Last Edit: January 10, 2013, 05:39:53 am by pablos » Logged

no comment

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

Nel 1° caso escludi il setup delle seriali, quindi escludi check sui buffer e interrupt.
Nel 2° caso togli solo i check per verificare se ci sono byte nei buffer, quindi il guadagno prestazionale è minore dato che  hai le ISR a rallentare lo sketch.

(se ho capito bene a quali porzioni di codice ti stai riferendo)
Logged


Genova
Offline Offline
Faraday Member
**
Karma: 40
Posts: 3446
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

(se ho capito bene a quali porzioni di codice ti stai riferendo)
http://arduino.cc/forum/index.php/topic,141254.60.html  Pag 5 #reply 70
« Last Edit: January 10, 2013, 03:52:19 am by pablos » 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

Nel 1° caso escludi il setup delle seriali, quindi escludi check sui buffer e interrupt.
Nel 2° caso togli solo i check per verificare se ci sono byte nei buffer, quindi il guadagno prestazionale è minore dato che  hai le ISR a rallentare lo sketch.

(se ho capito bene a quali porzioni di codice ti stai riferendo)

Le ISR di ricezione seriale vengono eseguite solo quando arrivano dei byte. Il solo fatto che siano attive non consuma cicli di CPU.
Logged

Genova
Offline Offline
Faraday Member
**
Karma: 40
Posts: 3446
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Insomma concludiamo questo treadh

"Hai una Mega? Bene, te la tieni così, se vuoi andare più forte di compri una UNO o un ARM!!"  smiley-mr-green smiley-mr-green
Logged

no comment

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

IMHO il 2° caso implica che il rallentamento indotto dalla creazione delle classi è minimo, quello che pesa molto è il check di serialEvent, sarebbe da capire quale istruzione o quale blocco di istruzioni rallenta così tanto e vedere se con il trucco dei buffer a null se non "beginnata" la serial può essere più veloce smiley-grin

ho provato a modificare il codice copn la storia del buffer, compila ma non testato (sono a lavoro), qualche buon anima che lo testa? allego il file HardwareSerial.cpp

edit: arduino 1.0.2

* HardwareSerial.cpp (14.15 KB - downloaded 52 times.)
Logged

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

Genova
Offline Offline
Faraday Member
**
Karma: 40
Posts: 3446
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Mmmmm da una barca di errori smiley
allego txt

* errori.txt (5.74 KB - downloaded 38 times.)
Logged

no comment

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

usa la arduino IDE 1.0.2
Logged

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

Pages: 1 ... 5 6 [7] 8   Go Up
Jump to: