et le compilateur (g++) me donne l'erreur que j'ai mise en sujet.
Est-ce que le code suivant, qui compile sans erreur, est équivalent à ce
que je veux faire ?
Faire des vecteurs de vecteurs pose des gros problèmes de gestion de mémoire et de temps d'accès aux éléments.
Mieux vaut faire comme le je démontrais, et comme le font tous les compilateurs de tous les autres languages qui eux supportent les tableaux multidimensionnels, (ce n'est pas "rocket-science" pourtant), une seule allocation, et un indexage direct.
Si on veut faire des grosses matrices et assimilees, en theorie, c'est valarray qui sert a ca. Je ne sais plus ou ca en est, j'ai un vague souvenir qu'il y avait des soucis (et des mises-a-jour en C++0x), mais je pense qu'un wandering Gaby pourra nous en dire plus, c'est pas comme si il n'etait pas responsable de l'implementation dans la libstdc++ de gcc...
In article <7ciqhkhoqr.fsf@pbourguignon.anevia.com>,
Pascal J. Bourguignon <pjb@informatimago.com> wrote:
Faire des vecteurs de vecteurs pose des gros problèmes de gestion de
mémoire et de temps d'accès aux éléments.
Mieux vaut faire comme le je démontrais, et comme le font tous les
compilateurs de tous les autres languages qui eux supportent les
tableaux multidimensionnels, (ce n'est pas "rocket-science" pourtant),
une seule allocation, et un indexage direct.
Si on veut faire des grosses matrices et assimilees, en theorie, c'est
valarray qui sert a ca. Je ne sais plus ou ca en est, j'ai un vague
souvenir qu'il y avait des soucis (et des mises-a-jour en C++0x), mais
je pense qu'un wandering Gaby pourra nous en dire plus, c'est pas comme
si il n'etait pas responsable de l'implementation dans la libstdc++ de
gcc...
Faire des vecteurs de vecteurs pose des gros problèmes de gestion de mémoire et de temps d'accès aux éléments.
Mieux vaut faire comme le je démontrais, et comme le font tous les compilateurs de tous les autres languages qui eux supportent les tableaux multidimensionnels, (ce n'est pas "rocket-science" pourtant), une seule allocation, et un indexage direct.
Si on veut faire des grosses matrices et assimilees, en theorie, c'est valarray qui sert a ca. Je ne sais plus ou ca en est, j'ai un vague souvenir qu'il y avait des soucis (et des mises-a-jour en C++0x), mais je pense qu'un wandering Gaby pourra nous en dire plus, c'est pas comme si il n'etait pas responsable de l'implementation dans la libstdc++ de gcc...
Lucas Levrel
Le 22 juillet 2009, Pascal J. Bourguignon a écrit :
Fabien LE LEZ writes: > std::vector<> répond à la demande. Il suffit de l'encapsuler dans une > classe qui va bien :
Faire des vecteurs de vecteurs pose des gros problèmes de gestion de mémoire et de temps d'accès aux éléments.
C'est pour ça qu'il ne le fait pas :-p
Mieux vaut faire comme le je démontrais
Ton code est un peu trop compliqué pour moi. Est-il facilement adaptable pour des tableaux à D dimensions ?
-- LL
Le 22 juillet 2009, Pascal J. Bourguignon a écrit :
Fabien LE LEZ <gramster@gramster.com> writes:
> std::vector<> répond à la demande. Il suffit de l'encapsuler dans une
> classe qui va bien :
Faire des vecteurs de vecteurs pose des gros problèmes de gestion de
mémoire et de temps d'accès aux éléments.
C'est pour ça qu'il ne le fait pas :-p
Mieux vaut faire comme le je démontrais
Ton code est un peu trop compliqué pour moi. Est-il facilement adaptable
pour des tableaux à D dimensions ?
Le 22 juillet 2009, Pascal J. Bourguignon a écrit :
Fabien LE LEZ writes: > std::vector<> répond à la demande. Il suffit de l'encapsuler dans une > classe qui va bien :
Faire des vecteurs de vecteurs pose des gros problèmes de gestion de mémoire et de temps d'accès aux éléments.
C'est pour ça qu'il ne le fait pas :-p
Mieux vaut faire comme le je démontrais
Ton code est un peu trop compliqué pour moi. Est-il facilement adaptable pour des tableaux à D dimensions ?
-- LL
Lucas Levrel
Le 22 juillet 2009, Fabien LE LEZ a écrit :
std::vector<> répond à la demande. Il suffit de l'encapsuler dans une classe qui va bien :
template <class T> class TableauTailleFixe3D
Merci ! Et pour mon instruction d'écriture, je fais simplement fileout.write((char*) &tab(i,0,0), 3*t*sizeof(double)); ? (Je suppose que oui grâce aux méthodes operator() que tu as définies, mais comme je ne connais presque rien au C++ je préfère demander !)
Par ailleurs, cette implémentation que tu proposes réveille une question que j'avais posée sur fclc il y a un mois, et qui n'avait pas eu de réponse (enfin, le fil a plein de messages mais pas précisément sur ladite question !). Pour résumer : soient les deux méthodes suivantes pour implémenter un tableau bidimensionnel dont les données n'ont pas besoin d'être contiguës,
1) double **tab; tab=new (double *)[m]; for(row=0;row<m;row++) tab[row]=new double[n]; Puis accès à l'élément (i,j) par tab[i][j]
2) double *tab; tab=new double[m*n]; int index(int row,int col){return row*n+col;}; Puis accès à l'élément (i,j) par tab[index(i,j)]
Par la méthode 1, l'accès se fait par deux déréférencements successifs. Par la méthode 2, il faut une multiplication, une addition, et un déréférencement. Si l'on étend ces méthodes au cas à D dimensions, la méthode 1 requiert D déréférencements, la méthode 2 (D-1) multiplications et additions, et un déréférencement. Qu'est-ce qui est le plus rapide ?
-- LL
Le 22 juillet 2009, Fabien LE LEZ a écrit :
std::vector<> répond à la demande. Il suffit de l'encapsuler dans une
classe qui va bien :
template <class T> class TableauTailleFixe3D
Merci ! Et pour mon instruction d'écriture, je fais simplement
fileout.write((char*) &tab(i,0,0), 3*t*sizeof(double));
? (Je suppose que oui grâce aux méthodes operator() que tu as définies,
mais comme je ne connais presque rien au C++ je préfère demander !)
Par ailleurs, cette implémentation que tu proposes réveille une question
que j'avais posée sur fclc il y a un mois, et qui n'avait pas eu de
réponse (enfin, le fil a plein de messages mais pas précisément sur ladite
question !). Pour résumer : soient les deux méthodes suivantes pour
implémenter un tableau bidimensionnel dont les données n'ont pas besoin
d'être contiguës,
1)
double **tab;
tab=new (double *)[m];
for(row=0;row<m;row++) tab[row]=new double[n];
Puis accès à l'élément (i,j) par tab[i][j]
2)
double *tab;
tab=new double[m*n];
int index(int row,int col){return row*n+col;};
Puis accès à l'élément (i,j) par tab[index(i,j)]
Par la méthode 1, l'accès se fait par deux déréférencements successifs.
Par la méthode 2, il faut une multiplication, une addition, et un
déréférencement. Si l'on étend ces méthodes au cas à D dimensions, la
méthode 1 requiert D déréférencements, la méthode 2 (D-1) multiplications
et additions, et un déréférencement. Qu'est-ce qui est le plus rapide ?
std::vector<> répond à la demande. Il suffit de l'encapsuler dans une classe qui va bien :
template <class T> class TableauTailleFixe3D
Merci ! Et pour mon instruction d'écriture, je fais simplement fileout.write((char*) &tab(i,0,0), 3*t*sizeof(double)); ? (Je suppose que oui grâce aux méthodes operator() que tu as définies, mais comme je ne connais presque rien au C++ je préfère demander !)
Par ailleurs, cette implémentation que tu proposes réveille une question que j'avais posée sur fclc il y a un mois, et qui n'avait pas eu de réponse (enfin, le fil a plein de messages mais pas précisément sur ladite question !). Pour résumer : soient les deux méthodes suivantes pour implémenter un tableau bidimensionnel dont les données n'ont pas besoin d'être contiguës,
1) double **tab; tab=new (double *)[m]; for(row=0;row<m;row++) tab[row]=new double[n]; Puis accès à l'élément (i,j) par tab[i][j]
2) double *tab; tab=new double[m*n]; int index(int row,int col){return row*n+col;}; Puis accès à l'élément (i,j) par tab[index(i,j)]
Par la méthode 1, l'accès se fait par deux déréférencements successifs. Par la méthode 2, il faut une multiplication, une addition, et un déréférencement. Si l'on étend ces méthodes au cas à D dimensions, la méthode 1 requiert D déréférencements, la méthode 2 (D-1) multiplications et additions, et un déréférencement. Qu'est-ce qui est le plus rapide ?
-- LL
pjb
Lucas Levrel writes:
Le 22 juillet 2009, Pascal J. Bourguignon a écrit :
Fabien LE LEZ writes: > std::vector<> répond à la demande. Il suffit de l'encapsuler dans une > classe qui va bien :
Faire des vecteurs de vecteurs pose des gros problèmes de gestion de mémoire et de temps d'accès aux éléments.
C'est pour ça qu'il ne le fait pas :-p
Mieux vaut faire comme le je démontrais
Ton code est un peu trop compliqué pour moi. Est-il facilement adaptable pour des tableaux à D dimensions ?
std::vector<> répond à la demande. Il suffit de l'encapsuler dans une classe qui va bien :
template <class T> class TableauTailleFixe3D
Merci ! Et pour mon instruction d'écriture, je fais simplement fileout.write((char*) &tab(i,0,0), 3*t*sizeof(double)); ? (Je suppose que oui grâce aux méthodes operator() que tu as définies, mais comme je ne connais presque rien au C++ je préfère demander !)
Je n'ai montré qu'un squelette, c'est à compléter. Pour les entrées/sorties, tout dépend du format que tu veux utiliser.
Par ailleurs, cette implémentation que tu proposes réveille une question que j'avais posée sur fclc il y a un mois, et qui n'avait pas eu de réponse (enfin, le fil a plein de messages mais pas précisément sur ladite question !). Pour résumer : soient les deux méthodes suivantes pour implémenter un tableau bidimensionnel dont les données n'ont pas besoin d'être contiguës,
1) double **tab; tab=new (double *)[m]; for(row=0;row<m;row++) tab[row]=new double[n]; Puis accès à l'élément (i,j) par tab[i][j]
2) double *tab; tab=new double[m*n]; int index(int row,int col){return row*n+col;}; Puis accès à l'élément (i,j) par tab[index(i,j)]
Par la méthode 1, l'accès se fait par deux déréférencements successifs. Par la méthode 2, il faut une multiplication, une addition, et un déréférencement. Si l'on étend ces méthodes au cas à D dimensions, la méthode 1 requiert D déréférencements, la méthode 2 (D-1) multiplications et additions, et un déréférencement. Qu'est-ce qui est le plus rapide ?
La seconde option est et sera de plus en plus la plus rapide. http://www.cs.virginia.edu/papers/Hitting_Memory_Wall-wulf94.pdf
-- __Pascal Bourguignon__
Lucas Levrel <lucas.levrel@univ-paris12.fr> writes:
Le 22 juillet 2009, Fabien LE LEZ a écrit :
std::vector<> répond à la demande. Il suffit de l'encapsuler dans une
classe qui va bien :
template <class T> class TableauTailleFixe3D
Merci ! Et pour mon instruction d'écriture, je fais simplement
fileout.write((char*) &tab(i,0,0), 3*t*sizeof(double));
? (Je suppose que oui grâce aux méthodes operator() que tu as définies,
mais comme je ne connais presque rien au C++ je préfère demander !)
Je n'ai montré qu'un squelette, c'est à compléter.
Pour les entrées/sorties, tout dépend du format que tu veux utiliser.
Par ailleurs, cette implémentation que tu proposes réveille une question
que j'avais posée sur fclc il y a un mois, et qui n'avait pas eu de
réponse (enfin, le fil a plein de messages mais pas précisément sur ladite
question !). Pour résumer : soient les deux méthodes suivantes pour
implémenter un tableau bidimensionnel dont les données n'ont pas besoin
d'être contiguës,
1)
double **tab;
tab=new (double *)[m];
for(row=0;row<m;row++) tab[row]=new double[n];
Puis accès à l'élément (i,j) par tab[i][j]
2)
double *tab;
tab=new double[m*n];
int index(int row,int col){return row*n+col;};
Puis accès à l'élément (i,j) par tab[index(i,j)]
Par la méthode 1, l'accès se fait par deux déréférencements successifs.
Par la méthode 2, il faut une multiplication, une addition, et un
déréférencement. Si l'on étend ces méthodes au cas à D dimensions, la
méthode 1 requiert D déréférencements, la méthode 2 (D-1) multiplications
et additions, et un déréférencement. Qu'est-ce qui est le plus rapide ?
La seconde option est et sera de plus en plus la plus rapide.
http://www.cs.virginia.edu/papers/Hitting_Memory_Wall-wulf94.pdf
std::vector<> répond à la demande. Il suffit de l'encapsuler dans une classe qui va bien :
template <class T> class TableauTailleFixe3D
Merci ! Et pour mon instruction d'écriture, je fais simplement fileout.write((char*) &tab(i,0,0), 3*t*sizeof(double)); ? (Je suppose que oui grâce aux méthodes operator() que tu as définies, mais comme je ne connais presque rien au C++ je préfère demander !)
Je n'ai montré qu'un squelette, c'est à compléter. Pour les entrées/sorties, tout dépend du format que tu veux utiliser.
Par ailleurs, cette implémentation que tu proposes réveille une question que j'avais posée sur fclc il y a un mois, et qui n'avait pas eu de réponse (enfin, le fil a plein de messages mais pas précisément sur ladite question !). Pour résumer : soient les deux méthodes suivantes pour implémenter un tableau bidimensionnel dont les données n'ont pas besoin d'être contiguës,
1) double **tab; tab=new (double *)[m]; for(row=0;row<m;row++) tab[row]=new double[n]; Puis accès à l'élément (i,j) par tab[i][j]
2) double *tab; tab=new double[m*n]; int index(int row,int col){return row*n+col;}; Puis accès à l'élément (i,j) par tab[index(i,j)]
Par la méthode 1, l'accès se fait par deux déréférencements successifs. Par la méthode 2, il faut une multiplication, une addition, et un déréférencement. Si l'on étend ces méthodes au cas à D dimensions, la méthode 1 requiert D déréférencements, la méthode 2 (D-1) multiplications et additions, et un déréférencement. Qu'est-ce qui est le plus rapide ?
La seconde option est et sera de plus en plus la plus rapide. http://www.cs.virginia.edu/papers/Hitting_Memory_Wall-wulf94.pdf
-- __Pascal Bourguignon__
Fabien LE LEZ
On Wed, 22 Jul 2009 14:41:00 +0200, (Pascal J. Bourguignon):
Mais tu as parlé de std::vector, ce qui en français se dit "vecteur".
Où as-tu encore été pêcher ça ?
On Wed, 22 Jul 2009 14:41:00 +0200, pjb@informatimago.com (Pascal J.
Bourguignon):
Mais tu as parlé de std::vector, ce qui en français se dit "vecteur".
On Wed, 22 Jul 2009 14:41:00 +0200, (Pascal J. Bourguignon):
Non.
Si. C'est du moins la méthode canonique. Comme je l'ai dit précédemment, il est possible que tu aies une bonne raison, dans des cas précis, de faire différemment. Dans ce cas, on étudie la situation minutieusement pour trouver la solution adaptée.
(Note : je parle bien de C++, pas de Lisp.)
On Wed, 22 Jul 2009 14:41:00 +0200, pjb@informatimago.com (Pascal J.
Bourguignon):
Non.
Si. C'est du moins la méthode canonique.
Comme je l'ai dit précédemment, il est possible que tu aies une bonne
raison, dans des cas précis, de faire différemment. Dans ce cas, on
étudie la situation minutieusement pour trouver la solution adaptée.
On Wed, 22 Jul 2009 14:41:00 +0200, (Pascal J. Bourguignon):
Non.
Si. C'est du moins la méthode canonique. Comme je l'ai dit précédemment, il est possible que tu aies une bonne raison, dans des cas précis, de faire différemment. Dans ce cas, on étudie la situation minutieusement pour trouver la solution adaptée.
(Note : je parle bien de C++, pas de Lisp.)
pjb
Fabien LE LEZ writes:
On Wed, 22 Jul 2009 14:41:00 +0200, (Pascal J. Bourguignon):
Non.
Si. C'est du moins la méthode canonique.
Oui, mais le canon des programmeurs C++...
Comme je l'ai dit précédemment, il est possible que tu aies une bonne raison, dans des cas précis, de faire différemment. Dans ce cas, on étudie la situation minutieusement pour trouver la solution adaptée.
(Note : je parle bien de C++, pas de Lisp.)
En fait, rien n'empêche de définir une classe (template) specifique pour des tableaux multidimentionnel. C'est juste une question d'imagination, mais il semble bien que les programmeurs C++ n'en soit pas capables, et se ramênent toujours à des vecteurs de vecteurs qu'ils ont appris à faire en C...
-- __Pascal Bourguignon__
Fabien LE LEZ <gramster@gramster.com> writes:
On Wed, 22 Jul 2009 14:41:00 +0200, pjb@informatimago.com (Pascal J.
Bourguignon):
Non.
Si. C'est du moins la méthode canonique.
Oui, mais le canon des programmeurs C++...
Comme je l'ai dit précédemment, il est possible que tu aies une bonne
raison, dans des cas précis, de faire différemment. Dans ce cas, on
étudie la situation minutieusement pour trouver la solution adaptée.
(Note : je parle bien de C++, pas de Lisp.)
En fait, rien n'empêche de définir une classe (template) specifique
pour des tableaux multidimentionnel. C'est juste une question
d'imagination, mais il semble bien que les programmeurs C++ n'en soit
pas capables, et se ramênent toujours à des vecteurs de vecteurs
qu'ils ont appris à faire en C...
On Wed, 22 Jul 2009 14:41:00 +0200, (Pascal J. Bourguignon):
Non.
Si. C'est du moins la méthode canonique.
Oui, mais le canon des programmeurs C++...
Comme je l'ai dit précédemment, il est possible que tu aies une bonne raison, dans des cas précis, de faire différemment. Dans ce cas, on étudie la situation minutieusement pour trouver la solution adaptée.
(Note : je parle bien de C++, pas de Lisp.)
En fait, rien n'empêche de définir une classe (template) specifique pour des tableaux multidimentionnel. C'est juste une question d'imagination, mais il semble bien que les programmeurs C++ n'en soit pas capables, et se ramênent toujours à des vecteurs de vecteurs qu'ils ont appris à faire en C...
-- __Pascal Bourguignon__
Lucas Levrel
Le 22 juillet 2009, Fabien LE LEZ a écrit :
La fonction write() ne doit pas modifier le tableau, donc le type est "char const*", pas "char*".
Ah oui, merci.
Note par ailleurs que toutes les données sont contiguës en mémoire. Tu peux donc écrire :
- Qu'est-ce que reinterpret_cast<> ? (Quelle différence par rapport au cast « bête » ?) - J'ai bien noté que c'est contigu, mais je n'écris pas toutes les « lignes » au même endroit, c'est pour ça que je disais &tab(i,0,0) - Au fait, dans cette classe que tu proposes, quel est l'avantage d'utiliser un vector plutôt que T *data et data=new T[taille1_*taille2_*taille3_] ?
-- LL
Le 22 juillet 2009, Fabien LE LEZ a écrit :
La fonction write() ne doit pas modifier le tableau, donc le type est
"char const*", pas "char*".
Ah oui, merci.
Note par ailleurs que toutes les données sont contiguës en mémoire. Tu
peux donc écrire :
- Qu'est-ce que reinterpret_cast<> ? (Quelle différence par rapport au
cast « bête » ?)
- J'ai bien noté que c'est contigu, mais je n'écris pas toutes les
« lignes » au même endroit, c'est pour ça que je disais &tab(i,0,0)
- Au fait, dans cette classe que tu proposes, quel est l'avantage
d'utiliser un vector plutôt que T *data et
data=new T[taille1_*taille2_*taille3_] ?
- Qu'est-ce que reinterpret_cast<> ? (Quelle différence par rapport au cast « bête » ?) - J'ai bien noté que c'est contigu, mais je n'écris pas toutes les « lignes » au même endroit, c'est pour ça que je disais &tab(i,0,0) - Au fait, dans cette classe que tu proposes, quel est l'avantage d'utiliser un vector plutôt que T *data et data=new T[taille1_*taille2_*taille3_] ?