Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Performance of size_t in C++

I translated the code here into C++ as follows

#include <iostream>

using namespace std;

int t = 20;

bool is_evenly_divisible(const int a, const int b) {
    for (int i=2; i<=b; ++i) { // Line 1
        if (a%i != 0)
            return false;
    }
    return true;
}

void run() {
    int i = 10;
    while (!is_evenly_divisible(i, t)) {
        i += 2;
    }
    cout << i << endl;
}

int main(int argc, char** argv) {
    run();
    return 0;
}

With the -O3 flag on compiler g++ 4.8.1 on Mac OSX 10.8.4, I get time 0.568s user time.

Now if I change the counter i in Line 1 in function is_evenly_divisible to size_t, the time suddenly jumps to 1.588s. This persists even if I change all of the variables to size_t, the time increases to 1.646s

What's happening? Shouldn't size_t increase performance rather than decreasing it as it's a more specific type than int?

like image 738
Opt Avatar asked Jun 29 '13 20:06

Opt


People also ask

When should I use Size_t in C?

size_t is commonly used for array indexing and loop counting. Programs that use other types, such as unsigned int, for array indexing may fail on, e.g. 64-bit systems when the index exceeds UINT_MAX or if it relies on 32-bit modular arithmetic.

Should I use Size_t instead of int?

When writing C code you should always use size_t whenever dealing with memory ranges. The int type on the other hand is basically defined as the size of the (signed) integer value that the host machine can use to most efficiently perform integer arithmetic.

Should I always use Size_t?

The reason why size_t is encouraged is because it makes your program portable. Typically a program should not need to care how much memory is installed in the machine it is running on. But if the program logic dictates that there will be a lower limit on the number of elements then you could use a smaller index type.


2 Answers

int is usually the fastest all-round type. This property isn't mandated by the standard, but it's usually the case for today's platforms. We've also got things like cstdint's int_fast32_t which is more properly guaranteed to be the fastest type that can hold at least 32 bits -- highly recommend them for perf-sensitive code!

size_t isn't intended to give a fast integer. Its purpose is to provide an integer that can hold the size of the largest sized object your platform's address space can contain. Typically size_t is equivalent to the largest "native" integer your CPU supports, but it doesn't have to be.

I'm going to guess that you're on a 64-bit platform. Generally a 64-bit platform has about equal perf for 32-bit and 64-bit ops, but you've hit the one place they typically aren't: div/mod can actually be 2-3x slower on a 64-bit integer. In this case if int is 32-bit and size_t is 64-bit, it explains the issue nicely.

See Agner Fog's instruction tables document for more info. For Intel's Sandy Bridge platform, it shows 32-bit div has a latency of 20-28 cycles while 64-bit div takes 30-94 cycles.

like image 199
Cory Nelson Avatar answered Sep 20 '22 01:09

Cory Nelson


Size of size_t is implementation-defined and if you are running 64-bit machine most of the compilers would make it 8-byte long.

Operations with 8-byte integers are usually slower than with 4-byte analogs.

like image 42
sasha.sochka Avatar answered Sep 21 '22 01:09

sasha.sochka