M
Mathieu Benoit
(I'm having trouble to post this, sorry if this mail comes
several times)
I'm trying to optimize the use of an integer array class,
and I found that one major problem is pointer aliasing.
I consider the following example:
--------------------------------------------------------
class IntTab
{
public:
IntTab(int n, int m) :
data(new int[n*m]), dim0(n), dim1(m) {
}
~IntTab() {
delete data;
}
int ni() const {
return dim0;
}
int nj() const {
return dim1;
}
int & operator()(int i, int j) {
return data[i*dim1+j];
}
const int & operator()(int i, int j) const {
return data[i*dim1+j];
}
void myjob(IntTab & a) const;
private:
int * const data;
const int dim0;
const int dim1;
};
void myjob(const IntTab & a, IntTab & b)
{
int i, j, k;
int ni = b.ni();
int nj = b.nj();
for (i=0, k=0; i<ni; i++)
for (j=0; j<nj; j++, k++)
b(k,0) = a(i,j);
}
void IntTab::myjob(IntTab & a) const
{
int a_j = a.dim1;
int ni = dim0;
int nj = dim1;
int i, j, k;
int * a_data = a.data;
int * my_data = data;
for (i=0, k=0; i<ni; i++)
for (j=0; j<nj; j++, k++)
a_data[k*a_j] = my_data[i*nj+j];
}
---------------------------------------------------------
"myjob" is poorly optimized by the compiler (g++ 3.2)
because it assumes that in the process of writing b, I could
silently update the pointers (a.data and b.data) and the
index counters (a.dim1 and b.dim1) which are used in the
loop. Indeed, making these variables local as in
IntTab::myjob is much better but of course I prefer to write
my algorithms with the operator() which allows to easily put
some asserts for debugging.
Strangely enough, changing my array for an array of double
leads to the same problem, even with "-fstrict-aliasing".
Moreover, the "restrict" keyword might help here but it is
not supported by g++. Is there another way to tell the
compiler that caching the pointers is safe while preserving
readability ?
Is there something special with g++3.2 ?
Thanks,
Benoit MATHIEU
several times)
I'm trying to optimize the use of an integer array class,
and I found that one major problem is pointer aliasing.
I consider the following example:
--------------------------------------------------------
class IntTab
{
public:
IntTab(int n, int m) :
data(new int[n*m]), dim0(n), dim1(m) {
}
~IntTab() {
delete data;
}
int ni() const {
return dim0;
}
int nj() const {
return dim1;
}
int & operator()(int i, int j) {
return data[i*dim1+j];
}
const int & operator()(int i, int j) const {
return data[i*dim1+j];
}
void myjob(IntTab & a) const;
private:
int * const data;
const int dim0;
const int dim1;
};
void myjob(const IntTab & a, IntTab & b)
{
int i, j, k;
int ni = b.ni();
int nj = b.nj();
for (i=0, k=0; i<ni; i++)
for (j=0; j<nj; j++, k++)
b(k,0) = a(i,j);
}
void IntTab::myjob(IntTab & a) const
{
int a_j = a.dim1;
int ni = dim0;
int nj = dim1;
int i, j, k;
int * a_data = a.data;
int * my_data = data;
for (i=0, k=0; i<ni; i++)
for (j=0; j<nj; j++, k++)
a_data[k*a_j] = my_data[i*nj+j];
}
---------------------------------------------------------
"myjob" is poorly optimized by the compiler (g++ 3.2)
because it assumes that in the process of writing b, I could
silently update the pointers (a.data and b.data) and the
index counters (a.dim1 and b.dim1) which are used in the
loop. Indeed, making these variables local as in
IntTab::myjob is much better but of course I prefer to write
my algorithms with the operator() which allows to easily put
some asserts for debugging.
Strangely enough, changing my array for an array of double
leads to the same problem, even with "-fstrict-aliasing".
Moreover, the "restrict" keyword might help here but it is
not supported by g++. Is there another way to tell the
compiler that caching the pointers is safe while preserving
readability ?
Is there something special with g++3.2 ?
Thanks,
Benoit MATHIEU