0

I have a simple math vector class with operators overloaded. I would like to get some timing results for my operators. I can easily time my +=, -=, *=, and /= by timing the following code:

Vector sum;
for(size_t i = 0; i<iter; ++i)
  sum += RandVector();
cout << sum << endl;

Then I can subtract the time it takes to generate iter random vectors. In my tests, Vector is 3 dimensional, iter = 10,000,000.

I tried to do a similar thing with +,-,*,/:

Vector sum;
for(size_t i = 0; i<iter; ++i)
  sum = sum + RandVector();
cout << sum << endl;

Then subtract the time it takes to generate iter random vectors and perform iter assignments, however this gives a "negative" time, leading me to believe either the compiler is optimizing the operation somehow, or something strange is going on.

I am using gcc-4.7.2 using -O3 on a Fedora Linux machine.

Here is my timing code:

clock_t start, k = clock();
do start = clock();
while(start == k);

F()();

clock_t end = clock();

double time = double(end-start)/double(CLOCKS_PER_SEC);
cout << time - time_iter_rand_v - time_iter_ass;

Here F is a function object which performs the code above. time_iter_rand_v is the time it takes to create iter random vectors and time_iter_ass is the time it took for iter assignment operations.

My question is then how to get accurate timing of just the operator+ function not any assignments or random vector generation?

Gauthier Boaglio
  • 10,054
  • 5
  • 48
  • 85
pippin1289
  • 4,861
  • 2
  • 22
  • 37

3 Answers3

1

You really can't get an accurate timing for something like that when optimization is on. The reason is due to the fact that the compiler has the ability to move code around.

If you make the time storage variables volatile, the position of them relative to each other are not subject to optimisation due to moving. However, the code around them are, unless they are assigning or calling functions that take volatile variables (this includes a volatile member function which makes *this volatile).

Optimisation can do a lot of odd things to the code if you are expecting linear execution.

Adrian
  • 10,246
  • 4
  • 44
  • 110
0

One basic benchmarking method is to use gettimeofday :

#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
#include <sys/types.h>

#include <cstring>



//-------------------  Handle time in milliseconds  ----------------------//

/*
 * Return 1 if the difference is negative, otherwise 0.
 */
int timeval_subtract(struct timeval *result, struct timeval *t2, struct timeval *t1)
{
    long int diff = (t2->tv_usec + 1000000 * t2->tv_sec) - (t1->tv_usec + 1000000 * t1->tv_sec);
    result->tv_sec = diff / 1000000;
    result->tv_usec = diff % 1000000;

    return (diff<0);
}

void timeval_print(struct timeval *tv)
{
    char buffer[30];
    time_t curtime;

    printf("%ld.%06ld", tv->tv_sec, tv->tv_usec);
    curtime = tv->tv_sec;
    strftime(buffer, 30, "%m-%d-%Y  %T", localtime(&curtime));
    printf(" = %s.%06ld\n", buffer, tv->tv_usec);
}

// usage :
/*

    struct timeval tvBegin, tvEnd, tvDiff;

    // begin
    gettimeofday(&tvBegin, NULL);

    // lengthy operation
    int i,j;
    for(i=0;i<999999L;++i) {
        j=sqrt(i);
    }

    //end
    gettimeofday(&tvEnd, NULL);

    // diff
    timeval_subtract(&tvDiff, &tvEnd, &tvBegin);
    printf("%ld.%06ld\n", tvDiff.tv_sec, tvDiff.tv_usec);


 */
Gauthier Boaglio
  • 10,054
  • 5
  • 48
  • 85
0

Just create a vector of RandVector()s and iterate through them. It will solve the problem of measuring the time of generation. As for assignment I think that it comes down to how compiler optimizes it.

Piotr Jaszkowski
  • 1,150
  • 9
  • 12