Optimization for automatic objects
Joachim Schoeberl
js@jku.at
Thu Oct 23 14:44:00 GMT 2003
Dear optimization experts,
I am using expression templates for linear algebra in large scale
scientific computing. In this programming style there occure many automatic
objects.
I am wondering about the code generated by gcc, serveral versions
including 3.3.2. and a recent 3.4 (experimental)
I have attached a complete small programme for computing
vector = scalar * (scalar * vector), and the generated assembly code of
func1.
The actual computation loop is optimized very well (after .L32:).
But, before that, there are many movements, which seem unnecessary to me,
and should be eliminated by some optimization pass.
Now, my questions are:
- is there an optimization flag eliminating these movements ?
- should I implement the objects differently ?
- will there be an optimizer in the near future ?
Thank you,
Joachim
#include <iostream>
using namespace std;
template <class T>
class Expr
{
T data;
public:
Expr (T d) : data(d) { ; }
double operator() (int i) const { return data(i); }
};
class Vector
{
int s;
double * data;
public:
Vector (int as) { s = as; data = new double[as]; }
double operator() (int i) const { return data[i]; }
double & operator() (int i) { return data[i]; }
template <class T>
Vector & operator= (Expr<T> expr)
{ for (int i = 0; i < s; i++) data[i] = expr(i); return *this; }
};
template <class T>
class ScaleExpr
{
double a;
T expr;
public:
ScaleExpr (double aa, T aexpr) : a(aa), expr(aexpr) { ; }
double operator() (int i) const { return a*expr(i); }
};
template <class T>
inline Expr<ScaleExpr<Expr<T> > > operator* (double aa, Expr<T> exp)
{
return ScaleExpr<Expr<T> > (aa, exp);
}
inline Expr<ScaleExpr<const Vector&> > operator* (double aa, const
Vector & exp)
{
return ScaleExpr<const Vector&> (aa, exp);
}
void func1 (Vector & a, Vector & b)
{
b = 1*(2*(3*(4*a)));
}
int main ()
{
Vector a(10), b(10);
for (int i = 0; i < 10; i++)
a(i) = i;
func1 (a, b);
for (int i = 0; i < 10; i++)
cout << "b(" << i << ") = " << b(i) << endl;
}
compilation with gcc3.3.2 called as:
gcc -S -O3 -finline-limit=10000 -ftemplate-depth-99 testexpr.cpp
.section .rodata.cst4,"aM",@progbits,4
.align 4
.LC1:
.long 1073741824
.align 4
.LC2:
.long 1077936128
.text
.align 2
.p2align 4,,15
.globl _Z5func1R6VectorS0_
.type _Z5func1R6VectorS0_, @function
_Z5func1R6VectorS0_:
.LFB1807:
pushl %ebp
.LCFI4:
xorl %ecx, %ecx
movl %esp, %ebp
.LCFI5:
pushl %edi
.LCFI6:
movl $1074790400, %edx
pushl %esi
.LCFI7:
pushl %ebx
.LCFI8:
subl $348, %esp
.LCFI9:
movl 8(%ebp), %edi
flds .LC2
movl %ecx, -168(%ebp)
movl -168(%ebp), %ecx
movl %edx, -164(%ebp)
movl -164(%ebp), %edx
fstpl -200(%ebp)
movl -196(%ebp), %ebx
movl %edi, -160(%ebp)
movl -200(%ebp), %eax
movl %edx, -148(%ebp)
movl %edi, -144(%ebp)
movl %edx, -212(%ebp)
movl %edi, -208(%ebp)
movl %edx, -188(%ebp)
movl %edi, -184(%ebp)
movl %eax, -136(%ebp)
movl %ebx, -132(%ebp)
movl %edx, -124(%ebp)
movl %edi, -120(%ebp)
movl %eax, -280(%ebp)
movl %ebx, -276(%ebp)
movl %edx, -268(%ebp)
movl %ecx, -152(%ebp)
movl %ecx, -216(%ebp)
movl %ecx, -192(%ebp)
movl %ecx, -128(%ebp)
movl %ecx, -272(%ebp)
movl %edi, -264(%ebp)
movl %eax, -240(%ebp)
movl -200(%ebp), %eax
flds .LC1
movl %edi, -224(%ebp)
movl %eax, -96(%ebp)
movl 8(%ebp), %eax
fstpl -248(%ebp)
movl -248(%ebp), %esi
fld1
movl %eax, -80(%ebp)
movl -244(%ebp), %edi
movl -200(%ebp), %eax
movl %ebx, -236(%ebp)
movl %edx, -228(%ebp)
movl %eax, -352(%ebp)
movl 8(%ebp), %eax
movl %ebx, -92(%ebp)
movl %edx, -84(%ebp)
movl %eax, -336(%ebp)
movl -200(%ebp), %eax
movl %ebx, -348(%ebp)
movl %edx, -340(%ebp)
movl %eax, -312(%ebp)
movl %ebx, -308(%ebp)
movl %ecx, -232(%ebp)
movl %esi, -104(%ebp)
movl %edi, -100(%ebp)
movl %ecx, -88(%ebp)
movl %esi, -360(%ebp)
movl %edi, -356(%ebp)
movl %ecx, -344(%ebp)
fstpl -328(%ebp)
movl %esi, -320(%ebp)
movl %edi, -316(%ebp)
movl %ecx, -304(%ebp)
movl 8(%ebp), %eax
movl %edx, -300(%ebp)
movl %edx, -44(%ebp)
movl 8(%ebp), %edx
movl %eax, -296(%ebp)
movl -328(%ebp), %eax
movl %edx, -40(%ebp)
movl 12(%ebp), %edx
movl %eax, -72(%ebp)
movl -324(%ebp), %eax
movl %ebx, -52(%ebp)
movl (%edx), %ebx
movl %eax, -68(%ebp)
movl -200(%ebp), %eax
movl %esi, -64(%ebp)
movl %edi, -60(%ebp)
movl %eax, -56(%ebp)
xorl %eax, %eax
cmpl %ebx, %eax
movl %ecx, -48(%ebp)
jge .L35
movl 8(%ebp), %edi
movl 4(%edx), %ecx
movl 4(%edi), %edx
.p2align 4,,15
.L32:
fldl -48(%ebp)
fmull (%edx,%eax,8)
fmull -56(%ebp)
fmull -64(%ebp)
fmull -72(%ebp)
fstpl (%ecx,%eax,8)
incl %eax
cmpl %ebx, %eax
jl .L32
.L35:
addl $348, %esp
popl %ebx
popl %esi
popl %edi
popl %ebp
ret
.LFE1807:
.size _Z5func1R6VectorS0_, .-_Z5func1R6VectorS0_
More information about the Gcc
mailing list