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