[Bug c++/12685] New: Compiler-generated copy constructor breaks optimization
Teddy dot Todorov at cern dot ch
gcc-bugzilla@gcc.gnu.org
Mon Oct 20 11:16:00 GMT 2003
PLEASE REPLY TO gcc-bugzilla@gcc.gnu.org ONLY, *NOT* gcc-bugs@gcc.gnu.org.
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=12685
Summary: Compiler-generated copy constructor breaks optimization
Product: gcc
Version: 3.3.2
Status: UNCONFIRMED
Severity: normal
Priority: P2
Component: c++
AssignedTo: unassigned at gcc dot gnu dot org
ReportedBy: Teddy dot Todorov at cern dot ch
CC: gcc-bugs at gcc dot gnu dot org
GCC build triplet: i686-pc-linux-gnu
GCC host triplet: i686-pc-linux-gnu
GCC target triplet: i686-pc-linux-gnu
A simple class with three "double" data members and some arithmetic operations
results in optimal executable code if a copy constructor is explicitly written,
but if the copy constructor is omitted (and therefore generated by the
compiler) the execution time of a simple test program is increased by a factor
of four!
This bug report may be related to bug 6880, but it may shed some additional
light on the problem:
- the compiler is clearly able to optimize correctly a member-by-member copy
constructor if it is explicitly written.
- the compiler-generated copy constructor should perform a member-by-member
copy
- the compiler-generated copy constructor breaks optimization.
The HEAD of cvs version as of today (20/10/2003) has the same behaviour
To reproduce the problem the program below should be compiled and timed twice:
c++ -O2 singlefile.cxx -DCOPY_CONSTRUCTOR; time ./a.out
c++ -O2 singlefile.cxx ; time ./a.out
On my PC the first execution takes 0.220 seconds, and the second 1.010 seconds
The only difference between the two is the removal of the copy constructor from
the class definition.
------------------------------------------------------------------------
class Basic3DVector {
public:
#ifdef COPY_CONSTRUCTOR
// copy constructor from same type
Basic3DVector( const Basic3DVector & p) :
theX(p.x()), theY(p.y()), theZ(p.z()) {}
#endif
/// construct from cartesian coordinates
Basic3DVector( const double& x, const double& y, const double& z) :
theX(x), theY(y), theZ(z) {}
double x() const { return theX;}
double y() const { return theY;}
double z() const { return theZ;}
Basic3DVector& operator+= ( const Basic3DVector& p) {
theX += p.x();
theY += p.y();
theZ += p.z();
return *this;
}
Basic3DVector& operator-= ( const Basic3DVector& p) {
theX -= p.x();
theY -= p.y();
theZ -= p.z();
return *this;
}
/// Scalar product, or "dot" product, with a vector of same type.
double dot( const Basic3DVector& v) const {
return x()*v.x() + y()*v.y() + z()*v.z();
}
private:
double theX;
double theY;
double theZ;
};
// vector sum and subtraction of same types
inline Basic3DVector
operator+( const Basic3DVector& v1, const Basic3DVector& v2) {
return Basic3DVector(v1) += v2;
}
inline Basic3DVector
operator-( const Basic3DVector& v1, const Basic3DVector& v2) {
return Basic3DVector(v1) -= v2;
}
// scalar product
inline double operator*( const Basic3DVector& v1, const Basic3DVector& v2) {
return v1.dot(v2);
}
double vectorCompute3( const Basic3DVector& v1,const Basic3DVector& v2)
{
return (v1+v2)*(v1-v2);
}
#include <iostream>
int main() {
typedef Basic3DVector Vector;
int N = 10000000;
double sum = 0;
for (int i=1; i<N; i++) {
double s(i);
Vector v1( s, 2*s, 3*s);
Vector v2( 0.8*s, 0.5*s, 0.3*s);
sum += vectorCompute3(v1, v2);
}
std::cout << "sum = " << sum << std::endl;
}
More information about the Gcc-bugs
mailing list