Pages: [1] 2   Go Down
Author Topic: Ottimizzare il codice per la velocità  (Read 1439 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Sr. Member
****
Karma: 0
Posts: 380
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Buongiorno a tutti, scusate la domanda...

Ho necessità di rendere una funzione il più veloce possibile (almeno nelle mie capacità)... Attualmente il codice è scritto in questo modo:

Code:
void eFire(unsigned int eTime){
  
  if(eTime>1000) eTime = 1000;
  if(eTime<70) eTime = 70;
  
  int eTimeMicro = (unsigned int)((1/eTime)*1000000);
  
  // Start first slider
  digitalWrite(FIRST, HIGH);
  delayMicroseconds(PULSE);
  digitalWrite(FIRST, LOW);
  
  delayMicroseconds(eTimeMicro);
  
  // Start 2nd slider
  digitalWrite(SECOND, HIGH);
  delayMicroseconds(PULSE);
  digitalWrite(SECOND, LOW);
}

C'è un modo? Cosa e come posso intervenire? In particolare mi chiedo quanto sono lenti i due if ed il calcolo di eTimeMicro? In teoria le digitalWrite potrei sostituirle con le rispettive istruzioni per la manipolazione delle porte... ma probabilmente non sono loro ad influire più di tanto.

Grazie.
« Last Edit: April 11, 2012, 02:22:35 am by GS88 » Logged

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

E' una bella domanda. Bisognerebbe prendere il codice macchina generato dal compilatore e mettersi lì col datasheet per capire ogni istruzione che trovi quanto tempo di calcolo porta via e fare 2 somme.
Logged


Offline Offline
Sr. Member
****
Karma: 0
Posts: 380
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

E' una bella domanda. Bisognerebbe prendere il codice macchina generato dal compilatore e mettersi lì col datasheet per capire ogni istruzione che trovi quanto tempo di calcolo porta via e fare 2 somme.

Azz... grazie Leo! Mica cosa da poco...

Supponendo che la parte che a me interessa (quella dei digitalWrite) sia il più veloce possibile nel momento in cui mi serve, portar fuori questa parte di codice mettendolo in una variabile che poi passo alla funzione eFire()? In pratica calcolare eTime fuori dalla funzione, quando la velocità mi interessa meno... dentro la eFire mi risparmi questi calcoli e gli passo solo il valore...

Code:
 if(eTime>1000) eTime = 1000;
  if(eTime<70) eTime = 70;
  
  int eTimeMicro = (unsigned int)((1/eTime)*1000000);
Logged

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

In teoria le digitalWrite potrei sostituirle con le rispettive istruzioni per la manipolazione delle porte... ma probabilmente non sono loro ad influire più di tanto.

Invece pesano moltissimo, poco meno di 2 uS l'una, ovvero di più di quello che ci mette la if per fare il confronto e assegnare il valore, se le sostituisci con le relativa scrittura diretta dei pin tramite registri ci vuole solo un ciclo macchina (62.5 nS).
C'è però da tenere in considerazione che dentro la funzione hai dei delay di svariati millisecondi, quindi non vale la pena perdere tempo a sostituire le digitalwrite che complessivamente incidono circa 10 us contro un delay minimo di 1 ms.

Altra cosa, questo calcolo è a dir poco assurdo, non funziona perché non puoi dividere 1 con un valore int e aspettarti un valore diverso da 0.

Code:
int eTimeMicro = (unsigned int)((1/eTime)*1000000);

Devi fare così:

Code:
unsigned int eTimeMicro = 1000000L/eTime;


Logged

Offline Offline
Sr. Member
****
Karma: 0
Posts: 380
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Grazie  smiley-red

se le digitalWrite hanno quei tempi (credevo di più)... ho ben poco da fare.



« Last Edit: April 11, 2012, 03:08:05 am by GS88 » Logged

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

scusate, ma vi preoccupate della velocità delle funzioni quando c'è una  delayMicroseconds(eTimeMicro); di mezzo?
secondo me quì c'è qualcosa che logicamente non funziona.
Logged

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

Offline Offline
Sr. Member
****
Karma: 0
Posts: 380
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

scusate, ma vi preoccupate della velocità delle funzioni quando c'è una  delayMicroseconds(eTimeMicro); di mezzo?
secondo me quì c'è qualcosa che logicamente non funziona.

in che senso logicamente non funziona?

Funziona tutto. Quello che volevo sapere è quanto quegli if, dentro questa funzione anzichè fuori, potessero influire sull'esecuzione della funzione stessa.

Ossia se, portandoli fuori e passando il parametro alla funzione anzichè far eseguire questi controlli al suo interno potesse dare qualche vantaggio.

Il codice che vedi esegue perfettamente quello che deve fare. E tutti i delay che ci sono devono per forza di cose esserci.

Al massimo, posso con delle prove limare le delayMicroseconds tra i due digitalWrite per vedere se riesco a togliere qualcosa.
« Last Edit: April 11, 2012, 05:01:03 am by GS88 » Logged

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

il fatto che ci siano errori logici non vuol dire che una cosa non funzioni. Si può spingere una automobile, ma se prima togli il freno a mano è più facile non trovi?

in questo caso il rallentamento del freno a mano è provocato dalle delay che hai sparso nel codice, che puoi sostituire con delle millis() se il tempo di attesa è > del tempo di esecuzione di tutto il loop.

gli if difficilmente sono ottimizzabili senza usare il codice macchina, ma per le digitalwrite puoi usare sbi & cbi (se non erro) che sono delle macro straveloci. se le cerchi nel forum dovresti trovare il codice in varie discussioni.
Logged

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

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

in questo caso il rallentamento del freno a mano è provocato dalle delay che hai sparso nel codice, che puoi sostituire con delle millis() se il tempo di attesa è > del tempo di esecuzione di tutto il loop.

Che poi è la stessa cosa che gli ho detto io visto che c'è almeno un delay lungo come minimo 1 ms (eTime = 1000) e come massimo 14.28 ms (eTime = 70), quindi assolutamente trascurabili i tempi di esecuzione delle if e delle digitalwrite.
Logged

Parma
Offline Offline
Edison Member
*
Karma: 21
Posts: 2388
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

La strada del datasheet con le istruzioni assembly è la strada del dolore.
Io in genere simulo con AVR Studio e controllo direttamente quanto impiegano le funzioni, molto comodo.

Ciao
Logged

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

Io in genere simulo con AVR Studio e controllo direttamente quanto impiegano le funzioni, molto comodo.

Con AvrStudio puoi simulare molto poco visti gli enormi limiti del suo simulatore, al limite lo fai tramite un ICE via hardware debug oppure con un DSO, meglio con un analizzatore di stati logici, utilizzando un pin come out per un impulso.
C'è sempre il sistema semplice di utilizzare la micros per misurare quanti microsecondi passano tra due punti distinti del programma.
Logged

Firenze, Italy
Offline Offline
Full Member
***
Karma: 0
Posts: 104
Dislessia portami via
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset


C'è sempre il sistema semplice di utilizzare la micros per misurare quanti microsecondi passano tra due punti distinti del programma.


Anche io opterei per questa opzione ed in base a quello che ottieni ti regoli per fare quello che ti serve
Logged

The brightest flame burns quickest

Offline Offline
Sr. Member
****
Karma: 0
Posts: 380
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Cerco di spiegare cosa fa il programma perchè non comprendo che vantaggi avrei andando ad usare la millis().

Allora, a parte le if che servono per calcolarmi i microsecondi di ritardo visualizzando dei valori 'leggibili' (sicuramente da chi userà il tutto), i delay servono per 'caricare' delle bobine. I tempi son quelli, sotto le bobine non vengono caricate.

Qual'è il vantaggio che avrei usando millis()?

La delayMicroseconds(eTimeMicro) mi serve per definire il ritardo di attivazione di una bobina rispetto all'altra. Anche qui quale vantaggio avrei ad usare una millis()?

Grazie.
Logged

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

attivi il pin, con la millis registri il tempo di attivazione, fai altro nel codice, nel frattempo ogni tanto (ogni loop di solito, ma puoi fare anche una funzione apposta che chiami quando ne hai voglia) controlli se hai superato il tempo di attesa, a quel punto disattivi il pin, ed eventualmente avvisi l'utente.
Come vedi ottieni una sorta di parallelismo, non sei bloccato nell'attesa ma puoi fare altro.
Logged

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

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

Qual'è il vantaggio che avrei usando millis()?

Nessuno ti ha detto di usare la millis(), ti è stato detto che il tempo minimo, 1 ms, del delay all'interno della tua funzione è talmente grande che è irrilevante il tempo necessario per eseguire le altre istruzioni della funzione.
Logged

Pages: [1] 2   Go Up
Jump to: