Faire Vectoriser une boucle avec icpc
Bonjour,
Voulant mimiquer le comportement de Fortran, je suis en train de faire mumuse en C++ pour faire une classe Array (d'abord en 1d).
Je pensais "naivement" que le compilateur intel pourrait facilement m'aider à vectoriser une simple boucle où j'utilise un opérateur () pour accéder à un champ:
bout du code de la class Array_1d:
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53
| template<class T,int Offset=DEF_OFFSET>
class Array_1d
{
private:
uint64_t n1;
int64_t o1;
T* RESTRICT ptr;
// Forbid the "pass by value" in function calls
Array_1d(const Array_1d<T,Offset>& rhs);
public:
// Constructors
Array_1d(const uint64_t d1=0);
Array_1d(const Range& r1);
// Destructor
~Array_1d();
// Array_1d<T> operators
const Array_1d<T,Offset>& operator=(const Array_1d<T,Offset>& rhs);
const Array_1d<T,Offset>& operator=(const T value);
inline const T& operator()(const int64_t& i) const
{
#ifdef CHECKBOUND
if (i<o1 || i>int64_t(o1+n1-1))
throw Error(1,"Out of bound");
#endif
return ptr[i-o1];
}
// OPERATEUR QUI DOIT ETRE VECTORISER EN BOUCLE SELON MOI !!!
inline T& operator()(const int64_t& i)
{
#ifdef CHECKBOUND
if (i<o1 || i>int64_t(o1+n1-1))
throw Error(1,"Out of bound");
#endif
return ptr[i-o1];
}
// Methods
inline const T* RESTRICT get_pointer() const {return ptr;}
inline T* RESTRICT get_pointer() {return ptr;}
inline uint64_t size1() const{return n1;}
inline Range range1() const{return Range(o1,o1+n1-1);}
void resize(const uint64_t n_d1);
void resize(const Range& r1);
void free();
}; |
RESTRICT est définit en tant que restrict avec le compilo intel, et je compile avec -O3 -xSSSE3 -restrict.
En ce qui concerne une simple boucle d'appel à l'opérateur, je fais:
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
|
int64_t i;
int64_t min,max;
Array_1d<float> array;
array.resize(Range(-200,400));
min=array.range1().min();
max=array.range1().max();
// Ne vectorise pas ???
for(i=min;i<=max;++i)
array(i)=1.5;
float* ptr=array.get_pointer();
// Vectorise !!!
for(i=min;i<=max;++i)
ptr[i]=1.5; |
Est ce que vous avez des idées? ou est ce qu'on arrive dans les limites du/des compilos C++ qui s'arretent juste à l'inline sans passer à l'étape d'optimisation d'après (la vectorisation)?
Faisant pas mal de calcul scientifique je trouve dommage de ne pas pouvoir vectoriser ce genre de chose... pour les performances c'est très important.
à vos commentaires !!!