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