Hi everyone !
I found the way to solve this fu**** head-ache problem ! Now, I got exactly the same result with a hand-rolled C loop and with template expression. In fact, the only thing I do is replace that sort of code :
struct MaClasse
{
inline MaClasse ();
// Other functions, but just declaration here !
}
inline MaClasse::MaClasse ()
{
}
// Other functions here !
By :
struct MaClasse
{
MaClasse () {}
// Other functions, declared and defined inside the struct
}
Before, when I ran the profiler with my code, I obtained everything (like the constructor to OpAdd <Vec3, Vec3>... Now, when I ran the profiler with all optimizations, I have... nothing :p. So it seems that the two compilers (Visual and GCC) couldn't inline my functions...
So now it works, but I try the excellent CML library and they have really better performance and I don't know why. I post a message on the forum, and he said he'll take a look at my code and answer here ;). For now, for those who are interested, here is the code :
[source code="cpp"]#ifndef VEC3_HPP#define VEC3_HPP#include "MathOps.hpp"class Vec3{ typedef double * iterator; typedef const double * const_iterator; public: // Constructeur par défaudouble Vec3 () {}; // Constructeur de copie Vec3 (const Vec3 & vec) { myValues[0] = vec.myValues[0]; myValues[1] = vec.myValues[1]; myValues[2] = vec.myValues[2]; } // Constructeur à pardoubleir de doublerois valeurs Vec3 (const double x, const double y, const double z) { myValues[0] = x; myValues[1] = y; myValues[2] = z; } // Initialise chaque composante du vecteur à 0 void Zero () { myValues[0] = myValues[1] = myValues[2] = 0.0; } // Surcharge de l'opérateur [] en lecture double operator[] (const size_t idx) const { return myValues[idx]; } // Surcharge de l'opérateur [] en écriture double & operator[] (const size_t idx) { return myValues[idx]; } // Surcharge de l'opérateur d'affectation avec un autre objet Vec3 Vec3 & operator= (const Vec3 & vec) { myValues[0] = vec.myValues[0]; myValues[1] = vec.myValues[1]; myValues[2] = vec.myValues[2]; return *this; } // Surcharge de l'opérateur d'affectation avec une expression template template <typename Expr> Vec3 & operator= (const Expr & myExpr) { // On affecte les valeurs grâce à la structure Assign //Assign<>::Assignment (myValues, myExpr); iterator i = begin(); //const_iterator iend = end(); iterator i2 = myExpr.begin(); *i = *i2; return *this; } // Renvoit un pointeur sur le premier élément iterator begin () {return myValues;} iterator end () {return myValues + 3;} const_iterator begin () const {return myValues;} const_iterator end () const {return myValues + 3;} private: double myValues [3];};#endif // VEC3_HPP
[source code="cpp"]#ifndef MATHOPS_HPP#define MATHOPS_HPPtemplate <typename L, typename R, typename OpTag>class Expression{ typedef double * iterator; typedef const double * const_iterator; public: // Constructeur Expression (const L & l, const R & r) : op1 (l), op2 (r) { } // Surcharge de l'opérateur []. Se charge d'évaluer l'expression double operator[] (const size_t idx) const { return OpTag::Evaluate (idx, op1, op2); } // Renvoit un pointeur sur le premier élément iterator begin () {return OpTag::Evaluate (0, op1, op2);} iterator end () {return OpTag::Evaluate (3, op1, op2);} const_iterator begin () const {return OpTag::Evaluate (0, op1, op2);} const_iterator end () const {return OpTag::Evaluate (3, op1, op2);} private: const L & op1; // Première opérande const R & op2; // Seconde opérande};// Additionstruct OpAdd{ template <typename L, typename R> static double Evaluate (const size_t idx, const L & l, const R & r) { return l[idx] + r[idx]; }};// Soustractionstruct OpSub{ template <typename L, typename R> static double Evaluate (const size_t idx, const L & l, const R & r) { return l[idx] - r[idx]; }};// Surcharge de l'opérateur +template <typename L, typename R>inline Expression <L, R, OpAdd> operator+ (const L & l, const R & r){ return Expression <L, R, OpAdd> (l, r);}// Structure Assign.template <int N = 0>struct Assign{ template <typename L, typename R> static void Assignment (L & l, const R & r) { l[N] = r[N]; Assign<N+1>::Assignment (l, r); }};// Spécialisation d'Assign lorsque N=3template <>struct Assign<3>{ template <typename L, typename R> static void Assignment (L & l, const R & r) { }};#endif // MATHOPS_HPP