ptr vs ref performance?? (test case)
Rob Willis
rob@e-critical.com
Thu Dec 14 17:48:00 GMT 2000
Well, I was trying to avoid posting code, but here it is... Also
attached the output from c++ -S. This was not a tight loop - see the
code. Also, for these kind of performance tests - i compile with NO
optimizations turned on.
-Rob
Tim Hollebeek wrote:
>
> Rob Willis writes ...
> >
> > ptr de-ref:
> > value = *tp;
> >
> > ref access;
> > value = tr;
> >
> > I substracted out the looping and assignment overheads in the
> > performance #'s above.
>
> (difference was 13% over 6 billion ops)
>
> For _really_ tight loops like this, benchmarks are dangerous since
> many naive assumptions go out the window.
>
> For example, "subtracting out loop overhead" may not be accurate since
> branch prediction, lookahead, pipelining, etc etc etc issues are
> likely to be a significant fraction of overall execution speed, and
> what instructions are inside the loop (# of instructions, alignment,
> data dependencies, delay slots, etc) can change the speed of the loop
> instructions.
>
> Similarly, "subtracting out assignment" makes no sense since the
> compiled code does not have a distinct assignment step, especially at
> high levels of optimization.
>
> For short snippets of code like this, benchmarks may provide
> information about what to look at, but one really should be looking at
> what assembly code is generated for each fragment and comparing the
> differences in generated assembly code instead of comparing timing
> differences. So I suggest compiling your tests with -S and posting
> the results. That will help experts notice how each fragment is being
> compiled, what the differences are, if either is suboptimal, etc.
--
Rob Willis
rob@e-critical.com
#include <iostream>
#include <sys/time.h>
class TimeStamp
{
public:
TimeStamp( unsigned long sec = 0, unsigned long usec = 0 )
: _sec(sec), _usec(usec) {}
static const TimeStamp getCurrentTime();
TimeStamp & operator-= (const TimeStamp & rts );
friend TimeStamp operator-(const TimeStamp & ltv, const TimeStamp & rts);
friend std::ostream & operator<< ( std::ostream & os, const TimeStamp & ts );
private:
unsigned long _sec;
unsigned long _usec;
};
const TimeStamp TimeStamp::getCurrentTime()
{
struct timeval tv;
gettimeofday( &tv, NULL );
return TimeStamp( tv.tv_sec, tv.tv_usec );
}
TimeStamp & TimeStamp::operator-= (const TimeStamp & rts )
{
_sec -= rts._sec;
if ( _usec >= rts._usec )
{
_usec -= rts._usec;
}
else
{
_sec--;
_usec = 1000000 - ( rts._usec - _usec );
}
return *this;
}
TimeStamp operator-(const TimeStamp & lts, const TimeStamp & rts)
{
TimeStamp tmp( lts );
tmp -= rts;
return tmp;
}
std::ostream & operator<< ( std::ostream & os, const TimeStamp & ts )
{
os << ts._sec;
os << " / ";
os << ts._usec;
os << " ";
return os;
}
#define LOOP_MAX 1200000000
int main()
{
std::cout << "=========== long long perf test ====" << std::endl;
{
TimeStamp start = TimeStamp::getCurrentTime();
for( int i = 0; i < LOOP_MAX; ++i )
{
}
TimeStamp stop = TimeStamp::getCurrentTime();
TimeStamp diff = stop-start;
std::cout << "baseline: " << diff << std::endl;
}
{
long value = 0;
long test = 5236;
TimeStamp start = TimeStamp::getCurrentTime();
for( int i = 0; i < LOOP_MAX; ++i )
{
value = test;
value = test;
value = test;
value = test;
value = test;
value = test;
value = test;
value = test;
value = test;
value = test;
}
TimeStamp stop = TimeStamp::getCurrentTime();
TimeStamp diff = stop-start;
std::cout << "long eq: " << diff << std::endl;
}
{
long value = 0;
long test = 5236;
long * t = &test;
TimeStamp start = TimeStamp::getCurrentTime();
for( int i = 0; i < LOOP_MAX; ++i )
{
value = *t;
value = *t;
value = *t;
value = *t;
value = *t;
value = *t;
value = *t;
value = *t;
value = *t;
value = *t;
}
TimeStamp stop = TimeStamp::getCurrentTime();
TimeStamp diff = stop-start;
std::cout << "long ptr-de-ref: " << diff << std::endl;
}
{
long value = 0;
long test = 5236;
long & t(test);
TimeStamp start = TimeStamp::getCurrentTime();
for( int i = 0; i < LOOP_MAX; ++i )
{
value = t;
value = t;
value = t;
value = t;
value = t;
value = t;
value = t;
value = t;
value = t;
value = t;
}
TimeStamp stop = TimeStamp::getCurrentTime();
TimeStamp diff = stop-start;
std::cout << "long ref access: " << diff << std::endl;
}
{
long value = 0;
struct T
{
long v1;
long v2;
} test;
test.v1 = 5236;
struct T * p1 = &test;
TimeStamp start = TimeStamp::getCurrentTime();
for( int i = 0; i < LOOP_MAX; ++i )
{
value = p1->v1;
value = p1->v1;
value = p1->v1;
value = p1->v1;
value = p1->v1;
value = p1->v1;
value = p1->v1;
value = p1->v1;
value = p1->v1;
value = p1->v1;
}
TimeStamp stop = TimeStamp::getCurrentTime();
TimeStamp diff = stop-start;
std::cout << "long struct ptr: " << diff << std::endl;
}
{
long value = 0;
struct T
{
long v1;
long v2;
} test;
test.v1 = 5236;
struct T & p1( test );
TimeStamp start = TimeStamp::getCurrentTime();
for( int i = 0; i < LOOP_MAX; ++i )
{
value = p1.v1;
value = p1.v1;
value = p1.v1;
value = p1.v1;
value = p1.v1;
value = p1.v1;
value = p1.v1;
value = p1.v1;
value = p1.v1;
value = p1.v1;
}
TimeStamp stop = TimeStamp::getCurrentTime();
TimeStamp diff = stop-start;
std::cout << "long struct ref: " << diff << std::endl;
}
std::cout << "=========== test done ====" << std::endl;
}
More information about the Gcc
mailing list