This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: Howto avoid temporaries instantiated fully?
- From: Joe Buck <Joe dot Buck at synopsys dot com>
- To: rguenth at tat dot physik dot uni-tuebingen dot de (Richard Guenther)
- Cc: gcc at gcc dot gnu dot org
- Date: Fri, 1 Mar 2002 09:30:14 -0800 (PST)
- Subject: Re: Howto avoid temporaries instantiated fully?
Richard Guenther writes:
> While designing an iterator for iterating a 3d grid for
> numerical physics, I stumbled over the problem, that gcc
> fully instantiates a temporary for an operator like
> [full compilable example attached, compile with g++ -S -O3 and
> see the difference in output for both methods]
>
> Iterator operator+(int i) const {
> Iterator it(*this);
> it.m_i += i;
> return it;
> }
>
> even if only the (updated) m_i field of the new instance
> is used (read once) in uses like
>
> array(i+1);
You've stumbled onto the biggest performance problem with g++ as it stands
today: structs and classes get assigned to memory too quickly, meaning
that temporary objects can't be optimized away. The result is just what
you are seeing: the object gets created and you wind up with expensive
dead stores.
The only case where this doesn't happen is when the struct/class has one
data member of a type that can be put in a register (e.g. a pointer or
native numeric type). In such cases the compiler is smart enough to
cancel the reference (from passing the object by const reference to the
inline function) and the dereference (inside the inline function and
leave the object in a register.
What this means is that with the current g++ there's a huge payoff if
you can figure out how to design an iterator so that it has only one
data member. Unfortunately this isn't always possible.
It also means that g++'s very good score on the Stepanov benchmark is
completely misleading. The reason is that all the iterators in that
benchmark have only one data member, thus there is almost no abstraction
penalty. In reality, there is a large abstraction penalty for iterators
that need two or more data members, though fortunately vector<T>::iterator
and list<T>::iterator only need one.