C++: grandes matrices

C++: grandes matrices - Programmation

Marsh Posté le 28-03-2001 à 21:36:02    

puis-je utiliser des "grandes" matrices (3000 X 3000) en c++. Si oui, comment ?
 
Ca marche pour le moment avec 1400x1400, mais quand j'augmente, il fait des erreurs...
 
Merci bien

Reply

Marsh Posté le 28-03-2001 à 21:36:02   

Reply

Marsh Posté le 28-03-2001 à 22:08:26    

j'ai deja fait des tableaux de 8 000 000 deoubles et ca marche mais le probleme c'est qu'il faut tout plein de memoire 64Mo et que sous win9x ca part tres rapidement en couille.
 
Mais tu veux faire quoi avec tes matrices : des multiplications, faire une inversion de matrice ?
 
Mais n tout cas ce que je peux dire, c'est que pour la creation j'ai deja fais de tres gros tableaux et ca marchait super bien.
c'est pour faire du tri (QuickSort).

Reply

Marsh Posté le 28-03-2001 à 22:09:08    

au fait y'a quoi dans la matrice ?

Reply

Marsh Posté le 28-03-2001 à 23:26:02    

Et comment tu les déclares tes matrices ??
 
C'est des "double" dedans...

Reply

Marsh Posté le 29-03-2001 à 00:04:42    

Je te conseille de faire un peu de recherche (bouquins, web) sur les matrice creuses (sparse matrices) si une bonne partie de tes 9 millions de coefs sont nuls.
A+,


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le 29-03-2001 à 08:47:09    

Evites d'allouer ca sur la pile...
essai d'allour chaque ligne independement tu seras moins tributaire de la fragmentation de la memoire.

Reply

Marsh Posté le 29-03-2001 à 09:50:09    

gilou a écrit a écrit :

Je te conseille de faire un peu de recherche (bouquins, web) sur les matrice creuses (sparse matrices) si une bonne partie de tes 9 millions de coefs sont nuls.
A+,




Par exemple tu vas sur www.netlib.org et tu fais une recherche avec "Sparse Matrix" et tu tomberas sur SparseLib++ v1.5
Tu peux lier cette bibliothèque à Lapack++ (algèbre linéaire) et à IML++ (méthodes de résolutions de systèmes itératives)

Reply

Marsh Posté le 29-03-2001 à 12:24:12    

Citation :

Et comment tu les déclares tes matrices ??


 
ben je ne me suis pas embeter pour declarer les matrices, j'avais fait :
 
 attention les yeux
 
double toto[1300][1300]; // c'est pas beau ca
 
tu veux en faire quoi des tes matrices ?

Reply

Marsh Posté le 29-03-2001 à 13:33:54    

darkoli a écrit a écrit :

Citation :

Et comment tu les déclares tes matrices ??


 
ben je ne me suis pas embeter pour declarer les matrices, j'avais fait :
 
 attention les yeux
 
double toto[1300][1300]; // c'est pas beau ca
 
tu veux en faire quoi des tes matrices ?




 :ouch:  
Quel talent ! :lol:

Reply

Marsh Posté le 29-03-2001 à 13:20:25    

darkoli a écrit a écrit :

Citation :

Et comment tu les déclares tes matrices ??


 
ben je ne me suis pas embeter pour declarer les matrices, j'avais fait :
 
 attention les yeux
 
double toto[1300][1300]; // c'est pas beau ca
 
tu veux en faire quoi des tes matrices ?




 
Ben ca dans une fonction ca prends 8 Megs sur la pile... elle fait combien ta pile ?
 
Alloue ligne par ligne et sur le tas.
du stype en C
double **matrix;
if (matrix = (double**)malloc(n*sizeof(double*)))
 for (i=0; i<n; i++)
 {
  matrix[i]=(double*)malloc(m*sizeof(double));
 }
 
Bon en C++ dans une class tu peux faire des vector<vector<double>> c'est encore mieux...

Reply

Marsh Posté le 29-03-2001 à 13:20:25   

Reply

Marsh Posté le 29-03-2001 à 18:10:44    

meme pas vrai, faire  
  =>double t[1300][1300]
 c'est la meme chose que :
  =>double** t=(double**)malloc(sizeof(double*)*1300);
    for (var i=0;i<1300;i++) t[i]=(double*)malloc(sizeof(double)*1300);
 
sauf que c'est moins chiant à ecrire.
et au pire, il y a les variables globales.

Reply

Marsh Posté le 29-03-2001 à 18:40:57    

En principe c'est pas pareil. L'un alloue sur le tas et l'autre sur la pile (plus gênant).

Reply

Marsh Posté le 30-03-2001 à 09:12:17    

darkoli a écrit a écrit :

meme pas vrai, faire  
  =>double t[1300][1300]
 c'est la meme chose que :
  =>double** t=(double**)malloc(sizeof(double*)*1300);
    for (var i=0;i<1300;i++) t[i]=(double*)malloc(sizeof(double)*1300);
 
sauf que c'est moins chiant à ecrire.
et au pire, il y a les variables globales.




 
Au contraire ca n'a rien a voir...
Comme le dit Verdoux l'allocation est faite sur le tas en non sur la pile, or sur la plupart des machine la taille de la pile est limitee.
De plus quand on fait double Mat[1000][1000], Mat est alloue d'un seul tenant soit un bloc de 1 000 000 de doubles, alors que avec les malloc on alloue 1000 blocs de 1000 doubles, si la memoire est fragmentee il est plus facile de trouver 1000 blocs de 8Ko plutot que 8Mo d'un bloc... (ayant programme en 16 bits sur PC il vallait mieux ne pas avoir de blocs de plus de 64 Ko...
 
Contrairement a une idee rependue declarer un tableau a deux dimension n'est pas declarer un tableau de tableau meme si c'est ce que dissent la plupart des bouquin. d'ailleur essaie de faire reference a **Mat au lieu de Mat[0][0] et tu verra, par contre *Mat marche et *(Mat+1000000-1)donne Mat[999][999]...
 
Essayez avant de dire que j'ai tort. Moi aussi j'ai ete surpris, au debut...

Reply

Marsh Posté le 30-03-2001 à 09:48:40    

Pour info j'ai lu une fois que la pile sous NT4 est limitée à  
1Mo, au dela le systeme considère que le programme est parti en  
boucle et donc envois une exception.

Reply

Marsh Posté le 30-03-2001 à 10:10:36    

a ben je ne savais pas. En fait le plus simple c'est la varibale global. Y'a pas de malloc a faire ety'a pas besoin de la passer en parametre. C'est un peu moins "propre" comme dirais certains mais efficace.
 
aufait c'est pour faire quoi geraldo

Reply

Marsh Posté le 30-03-2001 à 10:41:49    

darkoli a écrit a écrit :

a ben je ne savais pas. En fait le plus simple c'est la varibale global. Y'a pas de malloc a faire ety'a pas besoin de la passer en parametre. C'est un peu moins "propre" comme dirais certains mais efficace.
 
aufait c'est pour faire quoi geraldo




Ho rage! Ho desespoir! ho vieilliesse enemmie! que n'ai-je vecu que pour cette infamie!
 
L'art de la litote est ton fort on dirait.
 
De plus ca ne resoud que le pb de la pile... Pas celle de l'allocation d'un bloc...

Reply

Marsh Posté le 30-03-2001 à 13:54:39    

geraldo> Fait attention a preserve la localite de tes acces memoire quand tu manipule ta matrice car une matrice comme ca prend quand meme 36 Mo. Si tu parcours ta matrice betement en ligne de 3000 coefficients, tu vas te payer systematiquement un miss dans le cache a chaque acces.
Donc decompose tes acces a la matrice en bloques de taille raisonnables.

Reply

Marsh Posté le 31-03-2001 à 16:08:38    

En utilisant des pointeurs tu peux également passer ta matrice en paramêtre à une fonction sans déclarations globales.

Reply

Marsh Posté le 01-04-2001 à 10:51:30    

Il y a des cas où même l'allocation dans le tas ne réponds pas au problème pour les gros besoins en mémoire, car l'espace de mémoire virtuel autorisé pour un processus est limité: 2 gigas en théorie sur un système 32 bits, en pratique cela dépend de la place disponible sur la partition de swap.
 
La bonne solution est alors d'utiliser un fichier mappé en mémoire, le fichier étant créé sur une partition où on est certain d'avoir de la place. Windows 95 OSR2 et Windows 98, 98SE, et NT ou 2000 supportent les fichiers mappés en mémoire, de même que la majorité des systèmes Unix (mais avec des noms de fonctions système différents).
 
Si le système ne dispose pas des fichiers mappés (systèmes 16 bits tels que DOS, ou temps réel, ou Win32s, ou sous-système WOW16 sous NT, ainsi que tout système qui ne gère pas la notion de mémoire virtuelle), il faut soi-même gérer le cache en mémoire et les entrées-sorties, et cela complique le programme qui utilise la mémoire ainsi étendue, car la commutation sur disque n'est plus automatique mais doit être prévue dans le code qui utilise cette mémoire (afin de savoir si le segment de données qu'on va accéder est bien présent, et savoir quel segment moins sollicité on peut basculer efficacement sur disque).
 
En C++, on peut facilement créer un allocateur qui utilise un tas sur fichier mappé, et l'utilisation des fichiers mappés est TRES conseillée pour les programmes ayant besoin de beaucoup de mémoire de travail, si on ne veut pas solliciter trop lourdement le swap et tout le système d'exploitation.
 
Sachez que les performances d'un programme qui utilise un fichier mappé sont sensiblement identiques à celles d'un programme qui utilise l'allocation classique en mémoire virtuelle, même pour de toutes petites quantités de mémoire. En effet, le système ne procède aux échanges sur disque que quand cela est nécessaire, et n'accède pas du tout au disque si la mémoire virtuelle utilisée par le processus pour accéder au fichier mappé tient entièrement dans la mémoire physique. La seule différence est que l'échange de mémoire sur disque a lieu dans un fichier distinct utilisé par le processus, et non dans le fichier ou la partition de swap standard du système.
 
Mieux: le swap standard du système est généralement fragmenté en pages pour servir simultanément toutes les applications, et les pages sont mélangées entre tous les processus, et au sein des espaces réservés à chacun des processus eux-mêmes, et le swap peut ainsi s'avérer lors des accès BEAUCOUP plus lent qu'un fichier mappé dont le programme contrôle lui-même la disposition et la fragmentation interne (en allouant à des positions précises dans le bloc de mémoire virtuelle correspondant au fichier mappé) !!!
 
Dès lors, on n'a pas de raison de se priver des fichiers mappés et il est possible d'y allouer en une seule fois une grosse matrice du type double[3000][3000] sans fragmenter l'allocation: le programme n'en sera que plus performant, car il n'y a pas de table de pointeurs intermédiaires...

 

[edit]--Message édité par verdy_p--[/edit]

Reply

Marsh Posté le 01-04-2001 à 12:29:55    

intéressant ce post, j'ai appris des truc  :p


---------------
http://www.cheata.net le site qui vous donne la banane!
Reply

Marsh Posté le 28-04-2010 à 14:26:43    

verdy_p a écrit :

Il y a des cas où même l'allocation dans le tas ne réponds pas au problème pour les gros besoins en mémoire, car l'espace de mémoire virtuel autorisé pour un processus est limité: 2 gigas en théorie sur un système 32 bits, en pratique cela dépend de la place disponible sur la partition de swap.
 
La bonne solution est alors d'utiliser un fichier mappé en mémoire, le fichier étant créé sur une partition où on est certain d'avoir de la place. Windows 95 OSR2 et Windows 98, 98SE, et NT ou 2000 supportent les fichiers mappés en mémoire, de même que la majorité des systèmes Unix (mais avec des noms de fonctions système différents).
 
Si le système ne dispose pas des fichiers mappés (systèmes 16 bits tels que DOS, ou temps réel, ou Win32s, ou sous-système WOW16 sous NT, ainsi que tout système qui ne gère pas la notion de mémoire virtuelle), il faut soi-même gérer le cache en mémoire et les entrées-sorties, et cela complique le programme qui utilise la mémoire ainsi étendue, car la commutation sur disque n'est plus automatique mais doit être prévue dans le code qui utilise cette mémoire (afin de savoir si le segment de données qu'on va accéder est bien présent, et savoir quel segment moins sollicité on peut basculer efficacement sur disque).
 
En C++, on peut facilement créer un allocateur qui utilise un tas sur fichier mappé, et l'utilisation des fichiers mappés est TRES conseillée pour les programmes ayant besoin de beaucoup de mémoire de travail, si on ne veut pas solliciter trop lourdement le swap et tout le système d'exploitation.
 
Sachez que les performances d'un programme qui utilise un fichier mappé sont sensiblement identiques à celles d'un programme qui utilise l'allocation classique en mémoire virtuelle, même pour de toutes petites quantités de mémoire. En effet, le système ne procède aux échanges sur disque que quand cela est nécessaire, et n'accède pas du tout au disque si la mémoire virtuelle utilisée par le processus pour accéder au fichier mappé tient entièrement dans la mémoire physique. La seule différence est que l'échange de mémoire sur disque a lieu dans un fichier distinct utilisé par le processus, et non dans le fichier ou la partition de swap standard du système.
 
Mieux: le swap standard du système est généralement fragmenté en pages pour servir simultanément toutes les applications, et les pages sont mélangées entre tous les processus, et au sein des espaces réservés à chacun des processus eux-mêmes, et le swap peut ainsi s'avérer lors des accès BEAUCOUP plus lent qu'un fichier mappé dont le programme contrôle lui-même la disposition et la fragmentation interne (en allouant à des positions précises dans le bloc de mémoire virtuelle correspondant au fichier mappé) !!!
 
Dès lors, on n'a pas de raison de se priver des fichiers mappés et il est possible d'y allouer en une seule fois une grosse matrice du type double[3000][3000] sans fragmenter l'allocation: le programme n'en sera que plus performant, car il n'y a pas de table de pointeurs intermédiaires...
 
[edit]--Message édité par verdy_p--[/edit]


 
Bonjour,
 
Je voudrai apprendre à travailler avec les fichiers mappés en mémoire en C si possible (sinon vous m'expliquez en C++ et je l'adapte en C). Pourriez vous m'aider à surmonter les étapes SVP ça serait très sympa. Merci


---------------
" Les racines de l'éducation sont amers mais ses fruits sont doux "
Reply

Marsh Posté le 28-04-2010 à 16:04:46    

ca mérite une pelle d'or, pour un déterrage de 9 ans [:dawa]


---------------
last.fm
Reply

Marsh Posté le 28-04-2010 à 19:51:50    

theshockwave a écrit :

ca mérite une pelle d'or, pour un déterrage de 9 ans [:dawa]


 
 
C'est vrai vous avez raison, mais comme on dit, si un arbre grandit de nouveaux sous arbres poussent en dessous. Si vous avez un diplôme de Bac+3, il 10 ans, sachez que beaucoup cherche a en avoir cette année. Merci si tu peux m'aider


---------------
" Les racines de l'éducation sont amers mais ses fruits sont doux "
Reply

Marsh Posté le 29-04-2010 à 11:12:47    

Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

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