Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Performance swapping integers vs double

For some reason my code is able to perform swaps on doubles faster than on the integers. I have no idea why this would be happening.

On my machine the double swap loop completes 11 times faster than the integer swap loop. What property of doubles/integers make them perform this way?

Test setup

  • Visual Studio 2012 x64
  • cpu core i7 950
  • Build as Release and run exe directly, VS Debug hooks skew things

Output:

Process time for ints 1.438 secs

Process time for doubles 0.125 secs

#include <iostream>
#include <ctime>
using namespace std;

#define N 2000000000

void swap_i(int *x, int *y) {
    int tmp = *x;
    *x = *y;
    *y = tmp;
}

void swap_d(double *x, double *y) {
    double tmp = *x;
    *x = *y;
    *y = tmp;
}

int main () {
    int a = 1, b = 2;
    double d = 1.0, e = 2.0, iTime, dTime;
    clock_t c0, c1;

    // Time int swaps
    c0 = clock();
    for (int i = 0; i < N; i++) {
        swap_i(&a, &b);
    }
    c1 = clock();
    iTime = (double)(c1-c0)/CLOCKS_PER_SEC;

    // Time double swaps
    c0 = clock();
    for (int i = 0; i < N; i++) {
        swap_d(&d, &e);
    }
    c1 = clock();
    dTime = (double)(c1-c0)/CLOCKS_PER_SEC;

    cout << "Process time for ints " << iTime << " secs" << endl;
    cout << "Process time for doubles  " << dTime << " secs" << endl;
}

It seems that VS only optimized one of the loops as Blastfurnace explained.

When I disable all compiler optimizations and have my swap code inline inside the loops, I got the following results (I also switched my timer to std::chrono::high_resolution_clock):

Process time for ints 1449 ms

Process time for doubles 1248 ms

like image 622
smashbourne Avatar asked Sep 16 '12 01:09

smashbourne


1 Answers

You can find the answer by looking at the generated assembly.

Using Visual C++ 2012 (32-bit Release build) the body of swap_i is three mov instructions but the body of swap_d is completely optimized away to an empty loop. The compiler is smart enough to see that an even number of swaps has no visible effect. I don't know why it doesn't do the same with the int loop.

Just changing #define N 2000000000 to #define N 2000000001 and rebuilding causes the swap_d body to perform actual work. The final times are close on my machine with swap_d being about 3% slower.

like image 102
Blastfurnace Avatar answered Nov 03 '22 00:11

Blastfurnace