meilleur conteneur niveau temps d'accès

meilleur conteneur niveau temps d'accès - C++ - Programmation

Marsh Posté le 10-05-2007 à 16:22:03    

J'aurais besoin de vos conseils sur les conteneurs.
 
En C/C++ , j'ai besoin d'avoir des données stockées selon 5 paramètres indépendants.
 
Logiquement de base j'ai tenté un tableau a 5 dimensions en C, alloué en mémoire avec 5 boucles de malloc.
 
Le problème c'est qu'en acces c'est extremement lent. Seulement je ne vois pas comment faire autrement. :o

Reply

Marsh Posté le 10-05-2007 à 16:22:03   

Reply

Marsh Posté le 10-05-2007 à 16:26:58    

C/C++ n'est pas un langage !
 
Une base de données ?


---------------
Töp of the plöp
Reply

Marsh Posté le 10-05-2007 à 16:43:02    

_darkalt3_ a écrit :

C/C++ n'est pas un langage !
 
Une base de données ?


pardon ? :o
 
 
 
est ce que cela te conviendrait ?
http://boost.org/libs/multi_index/doc/index.html
 
une base de donnée serait effectivement une bonne solution.

Reply

Marsh Posté le 10-05-2007 à 16:44:17    

+1 sur le post de Darkalt, tu devrais préciser exactement ton langage.
 
Faudrait voir comment tu fais, parce que récupérer un élément dans un tableau type C pour un index donné, c'est instantané. En C++, le vector devrait correspondre à ce que tu cherches.
Si par contre ton code rame pour trouver un élément, c'est un tout autre sujet.
 
Edit: C est un langage. C++ est un langage.
Mais il faudrait savoir de quoi on parle. C/C++ ça veut rien dire...


Message édité par IrmatDen le 10-05-2007 à 16:45:05
Reply

Marsh Posté le 10-05-2007 à 16:45:09    


Ben oui, on a le C et le C++, mais pas C/C++.


---------------
Töp of the plöp
Reply

Marsh Posté le 10-05-2007 à 16:46:02    

oki ^^

Reply

Marsh Posté le 10-05-2007 à 16:56:00    

Arf non BDD c'est pas trop possible. C'est pour faire de la compression vidéo.
 
Je vous mets un bout de code sur ma fçon de malloc mon tableau , de le remplir , et la maniere dont j'y accede.
 

Code :
  1. void tp3::CalcTabCosDCT2()
  2. {
  3. TabCosDCT = (double *****)malloc(8 * sizeof(*TabCosDCT));
  4. if (TabCosDCT == NULL)
  5. {
  6.  flag_precal_dct = -1;
  7.  cout<< "NOK\n";
  8. }
  9. for (int x = 0; x != 8 && flag_precal_dct != -1; x++)
  10. {
  11.  TabCosDCT[x] = (double ****)malloc(8 * sizeof(**TabCosDCT));
  12.  if (TabCosDCT[x] == NULL)
  13.  {
  14.   flag_precal_dct = -1;
  15.   cout<< "NOK\n";
  16.  }
  17.  for (int y = 0; y != 8 && flag_precal_dct != -1; y++)
  18.  {
  19.   TabCosDCT[x][y] = (double ***)malloc(8 * sizeof(***TabCosDCT));
  20.   if (TabCosDCT[x][y] == NULL)
  21.   {
  22.    flag_precal_dct = -1;
  23.    cout<< "NOK\n";
  24.   }
  25.   for (int u = 0; u != 8 && flag_precal_dct != -1; u++)
  26.   {
  27.    TabCosDCT[x][y][u] = (double **)malloc(8 * sizeof(****TabCosDCT));
  28.    if (TabCosDCT[x][y][u] == NULL)
  29.    {
  30.     flag_precal_dct = -1;
  31.     cout<< "NOK\n";
  32.    }
  33.    for (int v = 0; v != 8 && flag_precal_dct != -1; v++)
  34.    {
  35.     TabCosDCT[x][y][u][v] = (double *)malloc(256 * sizeof(*****TabCosDCT));
  36.     if (TabCosDCT[x][y][u][v] == NULL)
  37.     {
  38.      flag_precal_dct = -1;
  39.      cout<< "NOK\n";
  40.     }
  41.    }
  42.   }
  43.  }
  44. }
  45. for (int x = 0; x != 8; x++)
  46.  for (int y = 0; y != 8; y++)
  47.   for (int u = 0; u != 8; u++)
  48.    for (int v = 0; v != 8; v++)
  49.     for (int val = 0; val != 256; val++)
  50.      TabCosDCT[x][y][u][v][val]= val * cos((2.0 * x + 1.0) * u * M_PI / 16.0) *
  51.      cos((2.0 * y + 1.0) * v * M_PI / 16.0);
  52. if (flag_precal_dct != -1)
  53. {
  54.  cout << "OK\n";
  55.  flag_precal_dct = 1;
  56. }
  57. }


 

Code :
  1. double tp3::GetValueFromTabCosDCT(int x, int y, int u, int v, int val)
  2. {
  3. return (TabCosDCT[x][y][u][v][val]);
  4. }


 

Code :
  1. double result;
  2. for (u = 0; u != 8; u++)
  3.        for (v = 0; v != 8; v++)
  4.              for (x = 0; x != 8; x++)
  5.                     for (y = 0; y != y; v++)
  6.                          for (val = 0; val != 256; val++)
  7.                            result = GetValueFromTabCosDCT(x, y, u, v, val);


Message édité par guynemer le 10-05-2007 à 17:04:12
Reply

Marsh Posté le 10-05-2007 à 16:57:55    

Parce que c/c++ n'est pas un langage.
Je ne suis pas assez clair ?


---------------
Töp of the plöp
Reply

Marsh Posté le 10-05-2007 à 17:15:24    

vector! Et si tu récupères une valeur hors champ, ton appli part dans les choux là :/
Et mis à part cette considération C++, tu es sûr que c'est la récupération d'une valeur qui prend du temps? Le lookup est quasi instatané si on vire les adressages qui sont de toutes façon difficilement compressible.
Si c'est ça qui pose souci, t'es bon pour faire un tableau 1D qui sera un tantinet plus rapide, mais faut vraiment que tu sois sûr que c'est cette partie qui rame... ce dont je doute légérement.

Reply

Marsh Posté le 10-05-2007 à 17:28:31    

si si c'est bien cette partie, moi non plus je m'y attendais pas.
 
Le pire c'est que si je ne fais pas appel aux données calculées, mais si je calcule les formules des cosinus dans mon result = bla bla bal, j'obtiens un temps d'execution inférieur...
 
Pour ce qui est par contre de taper en dehors des indices des tableaux, ca y'a pas de risques  :)

Reply

Marsh Posté le 10-05-2007 à 17:28:31   

Reply

Marsh Posté le 10-05-2007 à 17:43:56    

vous me conseillez d'imbriquer des vectors  en fait ?

Reply

Marsh Posté le 10-05-2007 à 18:10:02    

guynemer a écrit :

Le pire c'est que si je ne fais pas appel aux données calculées, mais si je calcule les formules des cosinus dans mon result = bla bla bal, j'obtiens un temps d'execution inférieur...


J'ai peur de pas comprendre: tu dis bien qu'avec ton code, le calcul d'un cos est plus rapide qu'une indexation? Tu as mesuré comment? Sur combien d'éléments?
 
Fais des tests avec un vector 1D puis un tableau 1D aussi tant qu'à faire.
 
(par contre, je suis pas le mieux placé pour t'aider à ce niveau je pense, mais ça m'intrigue un tantiner :D)

Reply

Marsh Posté le 10-05-2007 à 18:28:20    

oui c bien ce que je disais irmat, mais c super bizarre. Meme carrément illogique.
 
La je susi en train de refaire deux versions épurées pr comparer.L'une avec un tableau de double à 5 dim , et l'une avec 5 vectors imbriques

Reply

Marsh Posté le 10-05-2007 à 18:34:17    

deja passe à un conteneur mono dimensionnel avec dim1*dim2*dim3*dim4*dim5 éléments,
ça t'evitera de te tapper 5 niveaux d'indirections T_T et des milliards de cache misses.


Message édité par Joel F le 10-05-2007 à 18:34:49
Reply

Marsh Posté le 10-05-2007 à 20:04:35    

Finalement avec 5 vectors c'est pas jouable du tout , c'est 3-4 fois plus lent qu'en tableaux.
 
Sinon j'ai trouvé d'ou venaient mes pb de lenteur : J'étais resté en mode Debug sous Studio. En release, ca va 3-4 fois plus vite.
 
Par contre Joel je vois pas comment je pourrais faire en une seule dim.
 
Imagine j'ai x = 1 et y = 2 et aussi x = 2 et y = 1
 
tab[1 *2] ca sera pas la meme chose que tab[2 * 1], a moins qu'il y ait une subtilité que j'ai pas captée

Reply

Marsh Posté le 10-05-2007 à 20:29:13    

exemple simple : un tableau 2D de 5 lignes par 6 colonnes,
tu stockes les lignes les unes derriéres les autres dans un  
tableau de 5*6 = 30 éléments. L'accés à la ie ligne/je colonne se fait via tableau[j + i*6]. En gros tu remplaces les indirections par un caclul d'index.
 
Pour N dimensions, tu extrapoles la formule ;)

Reply

Marsh Posté le 10-05-2007 à 20:50:02    

Et tu crois qu'en faisant 5 multiplications (et 5 additions) j'irais plus vite qu'en ayant 5 dimensions ? Hum ... A tester remarque.

Reply

Marsh Posté le 10-05-2007 à 21:09:48    

Oui, c'est certain.

Reply

Marsh Posté le 10-05-2007 à 21:42:49    

guynemer a écrit :

Et tu crois qu'en faisant 5 multiplications (et 5 additions) j'irais plus vite qu'en ayant 5 dimensions ? Hum ... A tester remarque.


 
5 flops + 1 indirection << 5 indirections ;)
 
c'est deja testé ;) crois moi :p


Message édité par Joel F le 10-05-2007 à 21:43:36
Reply

Marsh Posté le 10-05-2007 à 22:18:13    

concretement une indirection ca se traduit par quoi ? plusieurs flops ?

Reply

Marsh Posté le 10-05-2007 à 22:21:48    

La taille de ta matrice est importante ?
 
Je me souviens avoir fait une appli ou je créé une matrice 4D de int, d'une taille trop grande (1000x1000 je crois), en fait c'est bien évidement la taille en mémoire de cette matrice qui faisait ramer toute mon appli, c'était plus que ma quantité de ram :d
 
Mais bon, si ta matrice ne grandit pas dans tes proportions énorme, ça ne sera pas ça le problème.

Reply

Marsh Posté le 10-05-2007 à 23:23:26    

la taille ouais si qd , ca fait 255 * 8 * 8 * 8 * 8 * taille d'un double

Reply

Marsh Posté le 10-05-2007 à 23:43:29    

IrmatDen a écrit :

Oui, c'est certain.


 
Ah bon ?!? Je pensais que quand on accède à un tableau multi-dimensionnel le compilo fait exactement ce que l'on ferait en codant la "technique" tableau 1D. Sauf que, dans mon esprit, le compilo ne pouvait que générer un code plus rapide.
 
Je vous crois, hein, mais j'aimerais bien comprendre. Sur 'std::vector< std::vector<...>> ' OK, avec un template de template ce serait vraiment une optimisation de derrière les fagots de transformer en tableau 1D. Mais sur x[][] qu'est-ce qui empêche le compilateur de transformer en tableau 1D, ou en ce qu'il veut et qu'il considère comme le + rapide ?
 
J'utilise tableau N dimensions --> tableau 1 dimension + petite routine d'accès uniquement quand N n'est pas connu à la compilation.
 
Sinon, y'a eu un p'tit thread vaguement lié ici : http://forum.hardware.fr/hfr/Progr [...] 3390_1.htm
 
Chsais pas si ça peut aider ou pas, mais c'est un peu sur le même thème.

Reply

Marsh Posté le 11-05-2007 à 00:03:25    

Hmm c'est pas bête ce que tu dis boulgakov.
 
Mais je crois que le mieux c'est de tester :)

Reply

Marsh Posté le 11-05-2007 à 00:41:02    

boulgakov a écrit :

Ah bon ?!? Je pensais que quand on accède à un tableau multi-dimensionnel le compilo fait exactement ce que l'on ferait en codant la "technique" tableau 1D. Sauf que, dans mon esprit, le compilo ne pouvait que générer un code plus rapide.
 
Je vous crois, hein, mais j'aimerais bien comprendre. Sur 'std::vector< std::vector<...>> ' OK, avec un template de template ce serait vraiment une optimisation de derrière les fagots de transformer en tableau 1D. Mais sur x[][] qu'est-ce qui empêche le compilateur de transformer en tableau 1D, ou en ce qu'il veut et qu'il considère comme le + rapide ?
 
J'utilise tableau N dimensions --> tableau 1 dimension + petite routine d'accès uniquement quand N n'est pas connu à la compilation.
 
Sinon, y'a eu un p'tit thread vaguement lié ici : http://forum.hardware.fr/hfr/Progr [...] 3390_1.htm
 
Chsais pas si ça peut aider ou pas, mais c'est un peu sur le même thème.


 
 
parce dans son code il fait des allocations explicites. (après si tu fais un vrai tableau tab[][].... là oui c'est déplié en tableau contigu)
 
c'est pas un bloc mémoire de doubles, c'est un bloc mémoire de pointeur de pointeur de pointeur, etc.... donc cache trashing, page fault & tout le bordel. (y'a ptet autant de conso mémoire en pointeurs qu'en double au bout d'un moment)
 
guynemer >> tu peux éliminer des multiplications en regardant la cohérence spaciale que tu peux obtenir dans l'utilisation ultérieure.  
ie dans le cas d'une image 2D, si tu traites pixel par pixel, bin tu fais qu'incrémenter un indice/pointeur, si tu traites des pixels aléatoires mais ligne par ligne, tu peux maintenir un pointeur sur chaque début de ligne (que tu avance de la taille d'une ligne) et que tu indexes en fonction du pixel aléatoire que tu veux traiter.
 
idem réorganiser pour que:
[grandeur variant le moins][un peu plus][encore un peu plus][le plus]
 
ie tab[45][5][8][4] et tab[45][5][8][6] risquent d'être distant de quelques octets, et seront peut-être dans la même ligne de cache  
 
alors que tab[4][8][5][45] et tab[6][8][5][45] ne seront certainement pas dans la même ligne, et distant de plusieurs Mo (cache-trashing, TLB miss, page-faults...)

Message cité 1 fois
Message édité par bjone le 11-05-2007 à 00:52:23
Reply

Marsh Posté le 11-05-2007 à 09:31:03    

boulgakov a écrit :

Ah bon ?!? Je pensais que quand on accède à un tableau multi-dimensionnel le compilo fait exactement ce que l'on ferait en codant la "technique" tableau 1D. Sauf que, dans mon esprit, le compilo ne pouvait que générer un code plus rapide.


 
Ce n'est vrai que pour les TABLEAUX pas les zones mémoires allouées dynamiquement et utilisés comme telles.
La sémantique de
 
float tab[N][M];
 
est fondamentalement différente de celle de :
 
float** tab;

Reply

Marsh Posté le 11-05-2007 à 09:35:48    

toutes ces ********* dès le matin, ça fout la gerbe. Boost !

Reply

Marsh Posté le 11-05-2007 à 09:49:01    

boost c'est bien :O

Reply

Marsh Posté le 11-05-2007 à 19:00:55    

Joel F a écrit :

Ce n'est vrai que pour les TABLEAUX pas les zones mémoires allouées dynamiquement et utilisés comme telles.
La sémantique de
 
float tab[N][M];
 
est fondamentalement différente de celle de :
 
float** tab;


 

bjone a écrit :

parce dans son code il fait des allocations explicites. (après si tu fais un vrai tableau tab[][].... là oui c'est déplié en tableau contigu)


 
Ouaip' (j'y ai pensé quelques minutes après avoir posté, mais j'ai eu la flemme d'éditer mon texte).
 

Reply

Marsh Posté le 11-05-2007 à 19:47:47    

c'est quoi boost ? On m'a glissé ce nom vite fait pas je n'en sais pas plus.
 
En plus visiblement on m'a conseillé de m'arranger pr calculer uniquement sur des INT plutot que des double ou float, et que ca acccélerarait de bcp le temps d'execution.

Reply

Marsh Posté le 11-05-2007 à 20:38:38    

float deja oui ca me parait mieux.
 
boost : http://www.boost.org

Reply

Marsh Posté le 11-05-2007 à 20:54:38    

j'ai commencé à regarder la doc merci. Maintenant je me demande si ca va me permettre de gagner du temps face à un "basique" gros tableau d'int si je pars sur une dim. Hum

Reply

Marsh Posté le 12-05-2007 à 08:21:04    

guynemer a écrit :

j'ai commencé à regarder la doc merci. Maintenant je me demande si ca va me permettre de gagner du temps face à un "basique" gros tableau d'int si je pars sur une dim. Hum


 
multi_array mais faut voir. Deja essaye effectivment ton gros tableau 1D ;)

Reply

Marsh Posté le 12-05-2007 à 09:25:23    

Joel F a écrit :

multi_array mais faut voir. Deja essaye effectivment ton gros tableau 1D ;)


[:romf]
C'est un grand classique dans le traitement d'images...:D


---------------
Can't buy what I want because it's free -
Reply

Marsh Posté le 12-05-2007 à 09:33:31    

skeye a écrit :

[:romf]
C'est un grand classique dans le traitement d'images...:D


Clairement ;)

Reply

Marsh Posté le 12-05-2007 à 09:47:08    

skeye a écrit :

[:romf]
C'est un grand classique dans le traitement d'images...:D


 
Tant qu'on est dans le sujet, est-ce que vous pensez qu'il peut y avoir un gain significatif à découper l'image en bandes verticales de X pixels de large (bon ça nécessite un effort préalable pour faire ce découpage) et de traiter séparément chaque bande afin d'éviter lors de la lecture de pixels alentours d'aller tapper 4km plus loin dans la mémoire parcequ'on lit des lignes un peu plus haut et qu'avec la largeur des lignes ça fait super loin en mémoire ?
( Pour info c'est pour faire des convolutions un peu grosses )


---------------
Me: Django Localization, Yogo Puzzle, Chrome Grapher, C++ Signals, Brainf*ck.
Reply

Marsh Posté le 12-05-2007 à 09:54:05    

0x90 a écrit :

Tant qu'on est dans le sujet, est-ce que vous pensez qu'il peut y avoir un gain significatif à découper l'image en bandes verticales de X pixels de large (bon ça nécessite un effort préalable pour faire ce découpage) et de traiter séparément chaque bande afin d'éviter lors de la lecture de pixels alentours d'aller tapper 4km plus loin dans la mémoire parcequ'on lit des lignes un peu plus haut et qu'avec la largeur des lignes ça fait super loin en mémoire ?
( Pour info c'est pour faire des convolutions un peu grosses )


ça dépend....si tu as des traitements à faire dans le sens horizontal qui te font passer d'une bande à l'autre, ça risque de pas être génial...d'autant que ça fait perdre de l'accélération dans le calcul des indices des pixels contigus, a priori.

 

'fin je pense pas que le gain de base soit super terrible, en fait...à moins d'avoir vraiment une image monstrueusement énorme en largeur...

Message cité 1 fois
Message édité par skeye le 12-05-2007 à 10:04:30

---------------
Can't buy what I want because it's free -
Reply

Marsh Posté le 12-05-2007 à 10:11:05    

skeye a écrit :

ça dépend....si tu as des traitements à faire dans le sens horizontal qui te font passer d'une bande à l'autre, ça risque de pas être génial...d'autant que ça fait perdre de l'accélération dans le calcul des indices des pixels contigus, a priori.


Je pensais justement me débrouiller pour ne pas avoir de changement de bande, comme ça au niveau des indices y'a pas de calcul plus complexe que le truc habituel.
Par contre, pas de changement de bande ça veut dire qu'on doit utiliser plus de mémoire en mettant des marges droites et gauches pour la convolution ....


---------------
Me: Django Localization, Yogo Puzzle, Chrome Grapher, C++ Signals, Brainf*ck.
Reply

Marsh Posté le 12-05-2007 à 11:44:09    

Y'a t'il des options de compilation utilisables sous VS 2005 pour optimiser le temps de calcul ? des flags à rajouter à la ligne de commande ? Eventuellement des flags pour pouvoir utiliser les instructions spécifiques des procs genre SSE, MMX , etc. ?

Reply

Marsh Posté le 12-05-2007 à 21:45:23    

sse mmx ca s'utilisent pas comme ça, à moins d'utiliser icc qui fait un boulot pas trop dégeu d'auto-vectorisation. sinon, cf ma sig :p

Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed