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

Lor*_*one 10 c int 64-bit 32bit-64bit

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

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

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

jan*_*neb 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];
}
Run Code Online (Sandbox Code Playgroud)

在 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
Run Code Online (Sandbox Code Playgroud)

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

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