有什么理由在64位CPU上使用32位整数进行常见操作吗?

时间:2012-06-06 10:14:13

标签: c 64-bit int 32bit-64bit

我想知道在64位程序上继续使用int(在x86和x86_64上都是32位)对于没有什么特殊的变量并且不需要跨越2 ^的变量是个好主意64,像迭代计数器一样,或者最好使用与CPU的字大小相匹配的size_t

当然,如果你继续使用int,你可以节省一半的内存,这可能意味着谈论CPU缓存,但我不知道如果在64位机器上每32位数都必须在任何使用之前扩展到64位。

编辑: 我已经用我的程序进行了一些测试(参见self answer,我仍然保持janneb的接受,因为它很好)。事实证明,性能有了显着提升。

4 个答案:

答案 0 :(得分:4)

对于数组索引和指针算法,与指针大小相同的类型(通常是size_t和ptrdiff_t)可以更好,因为它们避免了对寄存器进行零或符号扩展的需要。考虑


float onei(float *a, int n)
{
  return a[n];
}

float oneu(float *a, unsigned n)
{
  return a[n];
}

float onep(float *a, ptrdiff_t n)
{
  return a[n];
}

float ones(float *a, size_t n)
{
  return a[n];
}

在x86_64上使用GCC 4.4 -O2,生成以下asm:


    .p2align 4,,15
.globl onei
    .type   onei, @function
onei:
.LFB3:
    .cfi_startproc
    movslq  %esi,%rsi
    movss   (%rdi,%rsi,4), %xmm0
    ret
    .cfi_endproc
.LFE3:
    .size   onei, .-onei
    .p2align 4,,15
.globl oneu
    .type   oneu, @function
oneu:
.LFB4:
    .cfi_startproc
    mov %esi, %esi
    movss   (%rdi,%rsi,4), %xmm0
    ret
    .cfi_endproc
.LFE4:
    .size   oneu, .-oneu
    .p2align 4,,15
.globl onep
    .type   onep, @function
onep:
.LFB5:
    .cfi_startproc
    movss   (%rdi,%rsi,4), %xmm0
    ret
    .cfi_endproc
.LFE5:
    .size   onep, .-onep
    .p2align 4,,15
.globl ones
    .type   ones, @function
ones:
.LFB6:
    .cfi_startproc
    movss   (%rdi,%rsi,4), %xmm0
    ret
    .cfi_endproc
.LFE6:
    .size   ones, .-ones

可以看出,带有int和unsigned int索引(onei和oneu)的版本需要一个额外的指令(movslq / mov)来对寄存器进行符号/零扩展。

正如评论中所提到的,缺点是编码64位寄存器比32位部分占用更多空间,使代码大小膨胀。其次,ptrdiff_t / size_t变量需要比等效int更多的内存;如果你有这样的数组,它肯定会影响性能远远超过避免零/符号扩展的相对较小的好处。如果不确定,简介!

答案 1 :(得分:3)

就Cache而言,它将节省空间;缓存处理数据块,无论CPU是否请求单个地址或完整块等于缓存块大小。

因此,如果你问的是32位数字是否在64位机器上的高速缓存中占用了64位空间,那么答案是否定的,它们仍将为自己占用32位。所以一般来说,它会节省一些空间,特别是如果你使用频繁访问的大型数组等。

我个人认为,简单的int看起来比size_t简单,大多数编辑都无法识别size_t类型,因此如果您使用int语法突出显示也会更好。 ;)

答案 2 :(得分:3)

我正在编码hard spheres model。来源可以在github找到。

我尝试继续使用size_t作为用作数组索引的变量,并int使用其他操作,与字大小无关。性能提升显着:执行时间下降~27到24左右。

答案 3 :(得分:0)

这应该是编译器开发人员的决定。

int是“普通”有符号整数的自然类型。由编译器决定它是什么 如果在特定平台上使用64位整数有一个真正的优势,那么编译器开发人员应该使int 64位。标准允许。

如果编译器开发人员决定坚持使用32位整数,那么通常应该信任他 也许,在极少数情况下,经过大量的优化工作后,您会发现long效果更好。然后你可能想要改变。