Pages: 1 2 [3] 4   Go Down
Author Topic: Verificare SRAM utilizzata  (Read 3533 times)
0 Members and 1 Guest are viewing this topic.
Genova
Offline Offline
Faraday Member
**
Karma: 43
Posts: 3476
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

bhe direi che non è poco considerato che sono solo 2 misere var

scusa quei numeri indicano lo spazio rimasto?
sbaglio o è meglio dichiararle globali?


grazie
« Last Edit: November 22, 2012, 04:47:00 am by pablos » Logged

no comment

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

No, indicano l'occupazione (vedi la scritta xx% full tra parentesi).
Nel caso in oggetto meglio locali che globali.
Logged


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

bhe direi che non è poco considerato che sono solo 2 misere var

Sono due variabili che occupano 12 byte visto che la seconda è una stringa di 11 caratteri, infatti la differenza tra i due metodi è 9 byte ed è dovuta all'uso di puntatori, che vanno creati e usano memoria, per indirizzare i dati locali che si trovano nel heap e non occupano ulteriore spazio.
Da notare che se si richiamano molte funzioni annidate, ciascuna con variabili locali, c'è il rischio di andare in overflow heap con il conseguente possibile crash del programma oltre alla perdita di dati.
Su mcu di livello superiore esistono appositi interrupt per gestire queste condizioni di errore run time, sugli AVR non è previsto nulla di simile.
Logged

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

Da notare che se si richiamano molte funzioni annidate, ciascuna con variabili locali, c'è il rischio di andare in overflow heap con il conseguente possibile crash del programma oltre alla perdita di dati.
E' il rischio che si corre scrivendo funzioni ricorsive, che cioè richiamano sé stesse: ad ogni chiamata, si gonfia l'heap  smiley-sweat
In un computer con 4 GB di RAM non te ne accorgi, ma qui sì.
Logged


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

E' il rischio che si corre scrivendo funzioni ricorsive, che cioè richiamano sé stesse: ad ogni chiamata, si gonfia l'heap  smiley-sweat
In un computer con 4 GB di RAM non te ne accorgi, ma qui sì.

Vero, però mi viene il dubbio che il gcc-avr, per le mcu 8 bit, non permette la ricorsività delle funzioni proprio per via delle limitate dimensioni dello stack/heap, non sono sicuro al 100% mi ricordo di averlo letto da qualche parte e non ho mai verificato se è realmente così.
Se non hai info sicure in merito più tardi provo in pratica con uno sketch con funzione ricorsiva sia per vedere se è realmente possibile, sia per testare il reale limite prima del heap overflow.
Logged

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

Non ho info in merito.
Più tardi provo anch'io.

Nel frattempo segnale questa OTTIMA pagina:
http://www.nongnu.org/avr-libc/user-manual/malloc.html

Si vede bene come viene usata la memoria dal compilatore.
PS:
la memoria estesa può essere usata solo su alcune MCU Atmel (vedi Atmega128 e Atmega2560). NON su Atmega328.
Logged


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

Nel frattempo segnale questa OTTIMA pagina:
http://www.nongnu.org/avr-libc/user-manual/malloc.html

Ottima pagina.
Giusto per completezza dell'informazione è da tenere presente che il modo di utilizzare la memoria non dipende completamente dal linguaggio, che comunque pone dei paletti, ma dal compilatore e le scelte fatte da chi lo ha realizzato.
Ovvero il modo di utilizzo della memoria, sia come aree che come allocazione, non è detto che sia identico tra compilatori C diversi o tra diverse release dello stesso compilatore rivolte a processori molto diversi come core/risorse.

Logged

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

Sì, certo. Lì si parla del compilatore Gnu Avr-gcc che è quello usato dall'Arduino e da Atmel. Sicuramente un altro compilatore ottimizzerà in base a suoi metodi.

PS:
leggendo della ricorsione, mi par di capire che sia sconsigliata da tutti ma solo perché consuma un sacco di risorse, non tanto perché non sia implementata.
Intanto ho provato un piccolo algoritmo per calcolare la sequenza di Fibonacci in modo ricorsivo ed è andato in botto  smiley-sweat
Algoritmo scritto male  smiley-roll-blue
Questo funziona.
Code:
void setup() {
    Serial.begin(19200);
    delay(2000);
    Serial.println("Sequenza di Fibonacci");
    Serial.println(fib(20));
    Serial.println("Terminata");
}

void loop() {

}

unsigned long fib(unsigned int n)
{
    Serial.println("0");
    return n == 0 ? 0 : fib2(n, 0, 1);
}

unsigned long fib2(unsigned int n, unsigned long p0, unsigned long p1)
{
  Serial.println(p1, DEC);
  return n == 1 ? p1 : fib2(n - 1, p1, p0 + p1);
}
« Last Edit: November 22, 2012, 05:45:53 am by leo72 » Logged


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

Intanto ho provato un piccolo algoritmo per calcolare la sequenza di Fibonacci in modo ricorsivo ed è andato in botto  smiley-sweat

Se l'ha compilato vuol dire che è supportata, che poi vada in crash è normale smiley
Logged

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

Intanto ho provato un piccolo algoritmo per calcolare la sequenza di Fibonacci in modo ricorsivo ed è andato in botto  smiley-sweat

Se l'ha compilato vuol dire che è supportata, che poi vada in crash è normale smiley

Era scritto male a livello di codice.
Quello che ho messo l'ho scritto con una versione ottimizzata che ho trovato in rete e che non va in botto neanche con numeri elevati. Mi suona però strano, non è crashato neanche con 100000 numeri  smiley-twist
Logged


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

Quello che ho messo l'ho scritto con una versione ottimizzata che ho trovato in rete e che non va in botto neanche con numeri elevati. Mi suona però strano, non è crashato neanche con 100000 numeri  smiley-twist

Dipende da come usi la memoria, se ad ogni iterazione vengono aggiunti dati alla fine l'heap si riempie e va in overflow, se viene solo modificato il contenuto di una, o più, variabile/i non c'è problema, da notare che lo stack non viene incrementato ad ogni iterazione pertanto non va in overflow.
Intanto abbiamo accertato che su avr-gcc la ricorsività è permessa, sicuramente da usare con discernimento e consci delle complicazioni a cui si va incontro, oltretutto ha senso usarla solo per problemi che sono ricorsivi per loro natura, come il calcolo del fattoriale, altrimenti è meglio il classico modo tramite ciclo condizionale.
Logged

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

Una nota aggiuntiva riguardo lo stack e la ricorsione, in realtà viene sempre incrementato ad ogni iterazione ricorsiva, però viene automaticamente decrementato alla fine della stessa, c'è da dire che non vale per tutti i compilatori, dipende dal livello di ottimizzazione e da quanto sono "intelligenti", quindi è anche possibile che si verifichi un errore di stack overflow dopo tot iterazioni.
Logged

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

Intanto abbiamo accertato che su avr-gcc la ricorsività è permessa, sicuramente da usare con discernimento e consci delle complicazioni a cui si va incontro, oltretutto ha senso usarla solo per problemi che sono ricorsivi per loro natura, come il calcolo del fattoriale, altrimenti è meglio il classico modo tramite ciclo condizionale.
E' vero che la ricorsione rende alle volte più semplice la strutturazione del codice ma un algoritmo iterativo è generalmente più rapido per cui alla fine, secondo me, conviene usare più quest'ultima tecnica che la prima.
Logged


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


Dipende da come usi la memoria, se ad ogni iterazione vengono aggiunti dati alla fine l'heap si riempie e va in overflow, se viene solo modificato il contenuto di una, o più, variabile/i non c'è problema, da notare che lo stack non viene incrementato ad ogni iterazione pertanto non va in overflow.


ma questo come avviente? ogni volta che una funzione richiama se stessa deve fare una call mettendo nello stack quantomeno il punto di ritorno della procedura...mi sbaglio?
Boo non mi capisco... comunque penso che per provare a risolvere il problema si possa provare a dichiarare globale un puntatore ad uno o due array e in setup() procedere con il malloc... qualcosa dovrebbe andare meglio anche perchè qua non abbiamo 2k ma 8... in pratica anneghiamo in un mare  smiley-roll di ram che non usiamo
... poi domanda... perchè questo non mi crasha il leonardo che ha solo 2,5k di ram e i led continuano a lampeggiare? ...dove sto scrivendo?
Code:
/*
  Blink
  Turns on an LED on for one second, then off for one second, repeatedly.
 
  This example code is in the public domain.
 */
 
// Pin 13 has an LED connected on most Arduino boards.
// give it a name:
char prova1[1000];

char *prova2;
int led = 13;

// the setup routine runs once when you press reset:
void setup() {               
  // initialize the digital pin as an output.
  pinMode(led, OUTPUT);     
 
  prova2 = (char *) malloc(1000 * sizeof(char));

 
}

// the loop routine runs over and over again forever:
void loop() {
  int i;
  for (i = 0; i <1000; i++)
  {  prova1[i]=0;
   
    }
 for (i = 0; i <1000; i++)
  {  prova2[i]=0;
   
    }
   
   
  digitalWrite(led, HIGH);   // turn the LED on (HIGH is the voltage level)
  delay(1000);               // wait for a second
  digitalWrite(led, LOW);    // turn the LED off by making the voltage LOW
  delay(1000);               // wait for a second
}
Logged

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

qua non abbiamo 2k ma 8... in pratica anneghiamo in un mare  smiley-roll di ram che non usiamo
Guarda che gli Atmega328 hanno solo 2 kB di RAM, l'ho scritto diverse volte.

Quote
... poi domanda... perchè questo non mi crasha il leonardo che ha solo 2,5k di ram e i led continuano a lampeggiare? ...dove sto scrivendo?
Nella RAM. Proprio perché hai 2,5 kB di RAM, lo sketch riesce a "sopravvivere" con quel mezzo K in più.
Caricando questo sketch per controllare la memoria:
http://www.controllerprojects.com/2011/05/23/determining-sram-usage-on-arduino/
viene fuori che ci sono 363 byte ancora liberi.

Lo stesso sketch, compilato e caricato sulla mia scheda UNO, fa crashare il micro. Qui, infatti ci sono solo 2 kB di RAM.
Logged


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