Probleme de gestion de memoire ??????

MBALHOUSSE Messages postés 15 Date d'inscription mercredi 14 mai 2008 Statut Membre Dernière intervention 2 septembre 2008 - 17 juil. 2008 à 15:25
cs_rt15 Messages postés 3874 Date d'inscription mardi 8 mars 2005 Statut Modérateur Dernière intervention 7 novembre 2014 - 18 juil. 2008 à 16:35
Bonjour,


je sais pas si quelqu'un a deja eu ce probleme, je m'explique:

dans mon travail je developpe des bibliotheques numeriques, un projet lourd, avec trop de variable que j'utilise comme des arguments dans mes fonctions, la plupart des fonctions retourne des tableaux de 60 elements,
genre:
double *  fonction(types arguments)
                  { 
                     static double tab[60];
                        ...
                        ...
                     return tab;
                  }
chaque tableau est utilisé pour calculer un autre et ainsi de suite jusqu'au resultat final,
mon probleme c'est que au bout d'un moment l'ordinateur met trop de temps pour calculer le resultat.
je sais pas pourquoi?
Merci


 

3 réponses

cs_rt15 Messages postés 3874 Date d'inscription mardi 8 mars 2005 Statut Modérateur Dernière intervention 7 novembre 2014 13
17 juil. 2008 à 17:35
Salut,

Bin ça à l'air pas trop moche.
Quand on déclare des variables en "static", soit une zone leur est réservée dans le .exe, soit une zone leur est réservée dans le .exe tel qu'il est chargé en mémoire (section plus grande en mémoire que dans le fichier).

Bref, quand ton processus démarre, toutes les allocations sont faîtes, ce n'est pas comme si tu avais du malloc de partout.

Ta fonction renvoie un pointeur, autrement dit 32bits, ce qui est idéal.

Concernant les arguments, il faut aussi essayer au maximum de faire passer des pointeurs si possible (C'est à dire si tu ne les modifie pas dans la fonction appelée, ou si le fait de les modifier n'a pas d'importance). Par exemple, si tu as pleins d'arguments, tu peux essayer de les mettre dans une struct, et de passer à tes fonctions un pointeur sur cette struct. Cela éviter de recopier les arguments passés par valeur un par un.

void fonction(int a, int b)

typedef struct
{
  int a;
  int b;
} point;

void fonction(point* p)

La solution verte est censé être plus performante : on empile 4 octets au lieu de 8. Mais si on modifie les champs a et b de p dans la fonction, il sont aussi modifiés dans l'appelant.

Une solution alternative pour l'allocation, mais théoriquement moins performante (Encore qu'il faut se méfier avec les théories), serait d'allouer les tableaux dans les appelantes, dans la pile.

double *  fonction(types arguments, double* tab)
{                   
  return tab;
}

et l'appel :

double tab[60];
fonction(arguments, tab);

Le renvoie du pointeur ne te sert plus qu'à enchaîner les appels plus facilement :
fonction2(arguemnts2, fonction1(arguments1, tab));

Le fait d'utiliser cette méthode peut te permettre éventuellement de réemployer le même tableau sur plusieurs appels :
double tab[60];
fonction(arguments1, tab);
fonction(arguments2, tab);

Les processeurs aiment bien relire une mémoire qu'il ont lus récemment.

Concernant les optimisation en calcul numérique, tu peux essayer de paralléliser certains de tes calculs, via les possibilités offertes par les processeurs modernes. Outre la possibilité de thread simultanés sur un multi-pro, la plupart des processeurs actuels intègre MMX et certains des SSEs qui permettent d'appliquer la même opération à plusieurs données.
Mais ça demande du boulot d'exploiter cette possibilité, et faut que les calculs s'y prêtes.
0
Neo_Fr Messages postés 653 Date d'inscription mardi 6 décembre 2005 Statut Membre Dernière intervention 10 novembre 2014 2
17 juil. 2008 à 23:31
"Le fait d'utiliser cette méthode peut te permettre éventuellement de réemployer le même tableau sur plusieurs appels :
double tab[60];
fonction(arguments1, tab);
fonction(arguments2, tab); "

Il me semble que si le tableau est declarer en static c'est deja le meme qui sera reutiliser a chaque appelle de la fonction non?

Ex:

void Test1(void)
{
static int i = 4;
if(!i--) { printf("Test1(): i 0\n"); i 4; }
}

void Test2(void)
{
int i = 4;
if(!i--) { printf("Test2(): i 0\n"); i 4; }
}

int main(void)
{
int i;
for(i=16; i; i--) { Test1(); Test2(); }
return 0;
}

Neo_Fr
0
cs_rt15 Messages postés 3874 Date d'inscription mardi 8 mars 2005 Statut Modérateur Dernière intervention 7 novembre 2014 13
18 juil. 2008 à 16:35
Bah vi, mais on en a un par fonction.

double *  fonction1(types arguments)

  static double tab[60];
}

double *  fonction2(types arguments)

  static double tab[60];
}

Alors que si on le passe en argument, on en a qu'un, déclaré dans l'appelante.

void appelante()
{
  double tab[60];
  fonction1(arguments, tab);
  fonction2(arguments, tab);
}

Si il y a beaucoup de fonction dans le premier cas, la consommation mémoire = nb fonction * 60 * 8 octets.
Dans le deuxième, la consommation est indépendant du nombre de fonctions vu que c'est toujours le même qui est réutilisé (Mais ça peut être un problème : tout dépend de l'algo).

La consommation mémoire n'est pas franchement le problème ici, mais comme je l'ai dit plus haut, il est souvent préférable de lire et écrire toujours la même chose, de manière à rester dans les caches proco (L1, L2....)

M'enfin c'est vrai que 60 * 8 * n, ça reste pas grand chose.
0
Rejoignez-nous