oln 10.49: Tiny changes in point and dpoint

Index: olena/ChangeLog from Astrid Wang <astrid@lrde.epita.fr> * oln/core/point2d.hxx: Fix member function minus(). * oln/core/abstract/dpoint.hh: Add member function norm2(). Index: olena/oln/core/abstract/dpoint.hh --- olena/oln/core/abstract/dpoint.hh Thu, 07 Aug 2003 02:08:21 +0200 david (oln/d/28_dpoint.hh 1.16 640) +++ olena/oln/core/abstract/dpoint.hh Mon, 19 Jan 2004 17:49:12 +0100 astrid (oln/d/28_dpoint.hh 1.16 640) @@ -30,6 +30,7 @@ # include <mlc/type.hh> # include <oln/core/coord.hh> +# include <ntg/real/builtin_float.hh> namespace oln { @@ -135,6 +136,16 @@ return true; } + ntg::float_d + norm2(void) const + { + double norm = 0; + + for (unsigned i = 0; i < dim; ++i) + norm += nth(i) * nth(i); + return sqrt(norm); + } + static std::string name() { Index: olena/oln/core/point2d.hxx --- olena/oln/core/point2d.hxx Mon, 28 Jul 2003 14:14:03 +0200 david (oln/c/29_point2d.hx 1.5 640) +++ olena/oln/core/point2d.hxx Mon, 19 Jan 2004 16:44:56 +0100 astrid (oln/c/29_point2d.hx 1.5 640) @@ -114,7 +114,7 @@ inline point2d point2d::minus() const { - point2d p(row(), col()); + point2d p(-row(), -col()); return p; } -- astrid

Astrid Wang <wang_a@epita.fr> writes:
point2d::minus() const { - point2d p(row(), col()); + point2d p(-row(), -col()); return p; }
Ne vaut-il mieux pas écrire : point2d::minus() const { return point2d(-row(), -col()); } Car sinon il y a un risque que ceci se produise : * Appel du constructeur d'un point2d pour p avec (-row(), -col()). * Appel du constructeur par copie de point2d a l'emplacement de la valeur de retour, en dehors de la fonction. * Appel du destructeur de p. La deuxième syntaxe, elle, autorise le compilateur à appler directement le bon constructeur a l'emplacement de l'objet qui va recevoir la valeur de retour. cf. Thinking in C++, page 421, en bas. :) gcc en -O3 optimise le premier code de sorte a ce qu'il n'y ai pas de problèmes, mais icc ne le fait pas. Et en plus, je trouve que gcc n'est pas très correct en se permettant de telles optimisations, qui risque de changer le comportement attendu. Pour conclure, c'est ce genre de problème qui fait que vaucanson est beaucoup plus rapide quand on le compile avec gcc qu'avec icc. -- Thomas Claveirole thomas.claveirole@lrde.epita.fr

Thomas Claveirole wrote:
[...] cf. Thinking in C++, page 421, en bas. :)
gcc en -O3 optimise le premier code de sorte a ce qu'il n'y ai pas de problèmes, mais icc ne le fait pas. Et en plus, je trouve que gcc n'est pas très correct en se permettant de telles optimisations, qui risque de changer le comportement attendu.
Pour conclure, c'est ce genre de problème qui fait que vaucanson est beaucoup plus rapide quand on le compile avec gcc qu'avec icc.
il faut qu'on en parle

Thomas Claveirole <thomas.claveirole@lrde.epita.fr> writes:
Astrid Wang <wang_a@epita.fr> writes:
point2d::minus() const { - point2d p(row(), col()); + point2d p(-row(), -col()); return p; }
Ne vaut-il mieux pas écrire :
point2d::minus() const { return point2d(-row(), -col()); }
Car sinon il y a un risque que ceci se produise :
* Appel du constructeur d'un point2d pour p avec (-row(), -col()).
* Appel du constructeur par copie de point2d a l'emplacement de la valeur de retour, en dehors de la fonction.
* Appel du destructeur de p.
La deuxième syntaxe, elle, autorise le compilateur à appler directement le bon constructeur a l'emplacement de l'objet qui va recevoir la valeur de retour.
cf. Thinking in C++, page 421, en bas. :)
gcc en -O3 optimise le premier code de sorte a ce qu'il n'y ai pas de problèmes, mais icc ne le fait pas. Et en plus, je trouve que gcc n'est pas très correct en se permettant de telles optimisations, qui risque de changer le comportement attendu.
Changer le comportement en quoi par exemple ?
Pour conclure, c'est ce genre de problème qui fait que vaucanson est beaucoup plus rapide quand on le compile avec gcc qu'avec icc.
Intéressant :) Si on y gagne à tous les coups, alors il faudra jeter un oeil dans les différents fichiers d'Olena car on peut trouver ce genre d'écriture un peu partout dans Olena. -- astrid

Astrid Wang <wang_a@epita.fr> writes:
Changer le comportement en quoi par exemple ?
Dans des cas peu fréquents (et très moches) ou tu as des effets de bords dans le constructeur qui vont aller modifier autre chose que l'objet en construction. En effet, dans ces cas là, appeler deux constructeurs au lieu d'un, ce n'est pas forcément la même chose. Idem avec les déstructeurs. Cela-dit, je n'ai jamais vu d'exemple de tel cas. Simplement, théoriquement, ce n'est pas impossible. Un exemple classique serait d'afficher quelque chose dans le constructeur.
Si on y gagne à tous les coups, alors il faudra jeter un oeil dans les différents fichiers d'Olena car on peut trouver ce genre d'écriture un peu partout dans Olena.
Parfois, ce n'est pas toujours possible de procéder ainsi : ma_fonction() { MonObjet o; o.je_fait_des_trucs(); return o; } En particulier, il y a pas mal de fonction de ce genre dans Vaucanson. -- Thomas Claveirole thomas.claveirole@lrde.epita.fr

"Thomas" == Thomas Claveirole <thomas.claveirole@lrde.epita.fr> writes:
Thomas> Astrid Wang <wang_a@epita.fr> writes:
point2d::minus() const { - point2d p(row(), col()); + point2d p(-row(), -col()); return p; }
Thomas> Ne vaut-il mieux pas écrire : Thomas> point2d::minus() const Thomas> { Thomas> return point2d(-row(), -col()); Thomas> } Thomas> Car sinon il y a un risque que ceci se produise : Thomas> * Appel du constructeur d'un point2d pour p avec (-row(), -col()). Thomas> * Appel du constructeur par copie de point2d a l'emplacement de la Thomas> valeur de retour, en dehors de la fonction. Thomas> * Appel du destructeur de p. Thomas> La deuxième syntaxe, elle, autorise le compilateur à appler Thomas> directement le bon constructeur a l'emplacement de l'objet qui va Thomas> recevoir la valeur de retour. Pour autant que je sache, la première aussi, car elle est sujette à l'optimisation de la valeur de retour nommée (sur le net: "Named return value optimization" ou encore "RVO"). C'est un sujet qu'on a discuté il y a quelques années au labo, quelqu'un en a peut-être encore des traces quelque part. En tout cas c'est la raison pour laquelle on préfère écrire A operator+(const A& l, const A& r) { A a(l) a += r; return a; } plutôt que A operator+(const A& l, const A& r) { return A(l) += r; } Dans le premier cas le compilateur pour placer `a' directement à l'emplacement de la valeur de retour, pour éviter la copie. Dans le second cas compilateur ne sait pas a priori que l'adresse du résultat de `+=' est la même que celle de la variable temporaire créée pour A(l). (J'ai bien compris que tu n'es pas tout as fait dans ce cas là. Je justifie juste le comportement de gcc: la norme lui permet cette optimisation.) -- Alexandre Duret-Lutz

Alexandre Duret-Lutz <duret_g@lrde.epita.fr> writes: [...]
Pour autant que je sache, la première aussi, car elle est sujette à l'optimisation de la valeur de retour nommée (sur le net: "Named return value optimization" ou encore "RVO").
C'est un sujet qu'on a discuté il y a quelques années au labo, quelqu'un en a peut-être encore des traces quelque part.
En tout cas c'est la raison pour laquelle on préfère écrire
A operator+(const A& l, const A& r) { A a(l) a += r; return a; }
plutôt que
A operator+(const A& l, const A& r) { return A(l) += r; }
si le compilateur ne supporte pas nrvo, il est preferable de faire: A operator+(A l, const A& r) { return l += r; } cf. http://www.boost.org/libs/utility/operators.htm#symmetry les gars de boost ont choisi de supporter les deux syntaxes. d'apres leurs headers, cette optimisation est dispos seulement sur gcc >= 3.1 et icc >= 6. -- js@lrde.epita.fr | pouet@mouret.org "creating the future" (c) framfab

serial wrote:
[...] cf. http://www.boost.org/libs/utility/operators.htm#symmetry
les gars de boost ont choisi de supporter les deux syntaxes.
ils doivent avoir raison !
d'apres leurs headers, cette optimisation est dispos seulement sur gcc >= 3.1 et icc >= 6.
j'ai du code sur lequel on va pouvoir tester ça (en plus du code déjà écrit d'olena) (coucou js, coucou pollux)

Astrid Wang <wang_a@epita.fr> writes:
Index: olena/ChangeLog from Astrid Wang <astrid@lrde.epita.fr>
* oln/core/point2d.hxx: Fix member function minus(). * oln/core/abstract/dpoint.hh: Add member function norm2().
Index: olena/oln/core/abstract/dpoint.hh --- olena/oln/core/abstract/dpoint.hh Thu, 07 Aug 2003 02:08:21 +0200 david (oln/d/28_dpoint.hh 1.16 640) +++ olena/oln/core/abstract/dpoint.hh Mon, 19 Jan 2004 17:49:12 +0100 astrid (oln/d/28_dpoint.hh 1.16 640) @@ -30,6 +30,7 @@
# include <mlc/type.hh> # include <oln/core/coord.hh> +# include <ntg/real/builtin_float.hh>
#include <ntg/float.hh> C'est mieux d'utiliser les headers publics, ils regroupent les headers utiles.

Astrid Wang <wang_a@epita.fr> writes:
Index: olena/ChangeLog from Astrid Wang <astrid@lrde.epita.fr>
* oln/core/point2d.hxx: Fix member function minus(). * oln/core/abstract/dpoint.hh: Add member function norm2().
Index: olena/oln/core/abstract/dpoint.hh --- olena/oln/core/abstract/dpoint.hh Thu, 07 Aug 2003 02:08:21 +0200 david (oln/d/28_dpoint.hh 1.16 640) +++ olena/oln/core/abstract/dpoint.hh Mon, 19 Jan 2004 17:49:12 +0100 astrid (oln/d/28_dpoint.hh 1.16 640) @@ -30,6 +30,7 @@
# include <mlc/type.hh> # include <oln/core/coord.hh> +# include <ntg/real/builtin_float.hh>
#include <ntg/float.hh>
C'est mieux d'utiliser les headers publics, ils regroupent les headers utiles.
On peut peut-être utiliser #warning (+ #ifndef) pour guider l'utilisateur sur les bons headers ?
participants (7)
-
Akim Demaille
-
Alexandre Duret-Lutz
-
Astrid Wang
-
Nicolas Burrus
-
serial
-
Thierry Géraud
-
Thomas Claveirole