任何理由在64位CPU上使用32位整数进行常规操作?

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

当然,如果你继续使用int你可以节省一半的内存,这可能意味着有关CPU高速缓存的说法,但是我不知道在64位计算机上,每个32位数必须在使用前扩展到64位。

编辑:我用我的一个程序跑了一些测试(看到自己的答案,我仍然保持janneb的接受,但因为它是好的)。 事实证明,有显着的性能改进。


对于数组索引和指针算术,与指针大小相同的类型(通常是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更多的内存; 如果你有这样的数组,它肯定会影响性能,而不是避免零/符号扩展的相对小的好处。 如果不确定,个人资料!


在Cache方面,它会节省空间; 缓存处理数据块,而不管CPU是请求单个地址还是完整块等于缓存块大小。

所以如果你问32位数是否在64位机器的缓存里占用64位的空间,那么答案是否定的,他们仍然需要32位。 所以一般来说,它会为你节省一些空间,特别是当你使用频繁访问的大型数组时。

我个人认为,一个简单的int看起来比size_t简单,而且大多数编辑器不会识别size_t类型,所以如果使用int语法突出显示也会更好。 ;)


我正在编写一个小硬球模型。 源可以在github上找到。

我试图继续使用size_t作为用作数组索引的变量, int用于其他操作,与字大小无关。 性能提升非常显着:执行时间下降约27〜24。

链接地址: http://www.djcxy.com/p/24351.html

上一篇: Any reason to use 32 bit integers for common operations on 64 bit CPU?

下一篇: 64 bit ntohl() in C++?