Newsgroup: it.comp.lang.c++
Titolo: [?] Rallentamento conti

Salve a tutti,
sarei molto felice di sapere xche un ciclo che fa dei conti sempre uguali su
matrici di dimensione costante rallenta costantemente. Rallenta di un
fattore 10 o +.
13 matrici su 15 sono costanti e servono solo per calcolare le altre 2. La
soluzione viene campionata e registrata su file binario. Il prg definisce le
matrici, le riempe leggendo da file i valori (giusti, credetemi) e poi parte
con il ciclo. I risultati vanno bene, ma ci mette molto + del previsto.
Il nucleo fondamentale del prg e' questo:
/*-----------------------reg_colori----------------------------*/
void reg_colori(FILE *f1, float **v2)
{
     short int i, j;
     static unsigned char temp;
     for (i=1; i<=dim-1; i++)
     {
          for (j=1; j<=dim-1; j++)
          {
                /* qui assegna 4 valori prestabiliti (colori) ai vari stati
                    del mio sistema, definiti nei range sottostanti*/
               if (v2[i][j] <= 0.01) temp = 1;
               else if (v2[i][j] > 0.01 && v2[i][j] < 0.9 && v2[i][j] >\
                 v1[i][j]) temp = 2;
               else if (v2[i][j] >= 0.9) temp = 3;
               else temp = 4;
               fwrite (&temp,sizeof(temp),1,f1);
          }
     }
     return;
}
/*--------------------------eulero()-------------------------------*/
void eulero()
{
    FILE *f1;
    register short int i, j, count=0;
    register int t;
    time_t tempo_prec=0, tempo_att;
    float e2, sig, dv, dw, f=0, tau=0, id, **v2;
    v2=matrix(0,dim,0,dim);
    if((f1=fopen("risxx.dat","wb"))==NULL)
       nrerror("Errore apertura file risultati");
    printf("nfin= %d\n",nfin); /*il tempo finale*/
    printf("dim= %d\n",dim); /*dim matrici quadrate*/
 for(t=0;t<=nfin;t++)
       for (i=0; i<=ntreni-1; i++)
      {
           countpls[i]++; /* aggiorno il contatore di impulsi che lancio
                                    periodicamente nel sistema*/
      }
      for(i=1;i<=dim-1;i++)
      {
           for(j=1;j<=dim-1;j++)
           {
                  controllo_treni(t,i,j); /*vede se devo lanciare degli
                                                    impulsi*/
                  /* i conti della mia simulazione: stato elettrico del
                    tessuto atriale */
e2=((c1[i][j]+c2[i][j])*e1[i][j]+c3[i][j])/(c3[i][j]+c2[i][j]);
                  sig=(e1[i][j]*c1[i][j])/c2[i][j];
                  if(v1[i][j] < e1[i][j]) f=-c1[i][j]*v1[i][j];
                  else if(e1[i][j]<=v1[i][j] && v1[i][j]<e2)
                  f=c2[i][j]*(v1[i][j]-sig);
                  else if(v1[i][j] >= e2) f=-c3[i][j]*(v1[i][j]-1);
                  if(v1[i][j] < b1[i][j]) tau=u1[i][j];
                  else if(b1[i][j]<=v1[i][j] && v1[i][j]<b2[i][j])
                        tau=u2[i][j];
                  else if(v1[i][j]>=b2[i][j]) tau=u3[i][j];
                  id=gx[i-1][j-1]*(v1[i][j-1]-v1[i][j])+gx[i-1][j]*\
                       (v1[i][j+1]-v1[i][j])+gy[i-1][j-1]*(v1[i-1][j]\
                       -v1[i][j])+gy[i][j-1]*(v1[i+1][j]-v1[i][j]);
                 dv=f-w[i][j]+id+pls;
              dw=((a[i][j]*v1[i][j])-w[i][j])/tau;
              v2[i][j]=v1[i][j]+(dv*h)/cm[i][j]; /*v2 contiene lo stato
                                                                    attuale
del sistema*/
              w[i][j]=w[i][j]+dw*h;
           }
      }
     count++; /*contatore del camponamento soluzioni*/
     if(count==100)
     {
           tempo_att= clock();
           /*il tempo di calcolo tra 2 registrazioni: AUMENTA SEMPRE */
           printf("t= %d tempo= %ld\n",t,tempo_att - tempo_prec);
           tempo_prec = tempo_att;
           reg_colori(f1, v2);
           count=0;
     }
     for (i=1;i<=dim-1;i++)
     {
         for (j=1;j<=dim-1;j++)
              v1[i][j]=v2[i][j]; /*scambio stato attuale sistema con stato
                                                precedente (necessario x
conti) */
          }
     }
 }
    fclose(f1);
    free_matrix(v2,0,dim,0,dim);
 return;
}
Che dire? Qualunque suggerimento sara' il benvenuto.
Grazie a tutti.
Edoardo

 [...]
Solo una osservazione.
Forse sei sul newsgroup sbagliato.
Visto che i tuoi programmi sono puro C, ti converrebbe
postare su it.comp.lang.c.
Comunque ti suggerisco di passare al C++.
Sono finalmente disponibili delle librerie numeriche
C++ che offrono la stessa performance di codice scritto
a mano in C, ma che sono molto più immediate.
Manlio Perillo

 fattore 10 o +.
...
Io ho dei sospetti sulla funzione controllo_treni... e' una
funzione che e' dimostrato impiega un tempo indipendente dal
primo parametro ? La variabile ntreni e' costante per tutta
l'esecuzione del programma ?
Tieni anche presente che:
  La parola "register" non aiuta un granche' il compilatore.
  La tecnologia di compilazione e' ora spesso in grado di
  assegnare i registri in maniera ragionevole.
  Se il problema e' la velocita' dovresti evitare di usare
  variabili "short" per indici. Il tipo di dato "int" e'
  in generale quello con cui la CPU lavora piu' rapidamente...
  "short" dovrebbe essere utilizzato come storage se ci sono
  problemi di spazio.
  Quando si deve ottimizzare e' innanzitutto essenziale
  effettuare delle misurazioni. Dove e' esattamente che
  il codice impiega piu' tempo ? L'intuito a volte e'
  veramente un cattivo consigliere in questo campo;
  misurazione ed esperienza sono le parole chiave.
HTH
Andrea
--
----------------------------------------------------------------
 <\___/>  Andrea        email: agriff at tin dot it
 / . . \  "6502"          irc: _6502_@EFNET#italia
(  (")  ) Griffini   homepage: 
http://www.netservers.com/~agriff
Sent via Deja.com 
http://www.deja.com/
Before you buy.


Sto graficando il tempo di calcolo tra i vari step. Fluttua a seconda dello
stato del tessuto (non dovrebbe) e schizza in alto quando stranamente (!) lo
stato si blocca su un range che inibisce ulteriori variazioni.
Inizio a pensare che aver reso la maggior parte delle variabili globali non
sia pagante. Anche se mi sembra che il problema si presenti anche nelle
versioni precedenti del programma, dove sono tutte locali.
Edoardo

 versioni precedenti del programma, dove sono tutte locali.
Le variabili locali sono create nello stack e questo normalmente
offre buona localita' di caching. Se si trattasse di un problema
di cache trashing pero' sarei stupito della dipendenza dal numero
di iterazione (in fondo manipoli sempre gli stessi elementi di
memoria, giusto ?)
HTH
Andrea
PS: A (s)proposito... perche' it.comp.lang.c++ ?



In effetti ad un certo punto genera un -Inf e da li macina solo NaN che
suppongo significhi non calcolabile. Ora controllero' che le costanti siano
tali.
Il sistema eccitabile dovrebbe rimanere tra -0.2 e 0.99 e prima di Inf e' a
0.22. Vedremo.
Edoardo

Scoperto il problema: le costanti caricate da file erano sbagliate xche c'e'
un errore nel prg che genera i file di input. Il tempo di calcolo fluttua
normalmente.
Grazie a tutti della collaborazione.
Edoardo