C ++中size_t的性能

时间:2013-06-29 20:58:38

标签: c++ performance c++11 int size-t

我将代码here翻译成C ++,如下所示

#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;
}

在Mac OSX 10.8.4上使用编译器g ++ 4.8.1上的-O3标志,我得到0.568s用户时间。

现在如果我将第1行中的计数器i更改为函数is_evenly_divisible到size_t,则时间会突然跳到1.588秒。 即使我将所有变量更改为size_t,时间也会持续存在,时间会增加到1.646s

发生了什么事? size_t不应该提高性能而不是降低性能,因为它是比int更具体的类型吗?

2 个答案:

答案 0 :(得分:17)

int通常是最快的全能型。此属性不是标准规定的,但通常情况下今天的平台。我们还得到了类似cstdint的int_fast32_t这样的东西,它更适合保证成为能保持至少32位的最快类型 - 强烈推荐它们用于性能敏感的代码!

size_t无意提供快速整数。其目的是提供一个整数,该整数可以保存平台地址空间可以包含的最大对象的大小。通常size_t相当于CPU支持的最大“本机”整数,但不一定如此。

我猜你是在64位平台上。通常,64位平台对于32位和64位操作具有大约相等的性能,但是您已经达到了通常不是的一个位置:div / mod实际上在64位整数上可能慢2-3倍。在这种情况下,如果int为32位且size_t为64位,则可以很好地解释该问题。

有关详细信息,请参阅Agner Fog's指令表文档。对于英特尔的Sandy Bridge平台,它显示32位div的延迟为20-28个周期,而64位div则需要30-94个周期。

答案 1 :(得分:1)

size_t的大小是实现定义的,如果你运行64位机器,大多数编译器都会使它长8字节。

使用8字节整数的操作通常比使用4字节模拟的操作慢。