[英]Any reason to use 32 bit integers for common operations on 64 bit CPU?
我想知道在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
,語法高亮也會更好。 ;)
這應該是編譯器開發人員的決定。
int
是“普通”有符號整數的自然類型。 由編譯器決定它是什么。
如果在特定平台上使用64位整數有一個真正的優勢,那么編譯器開發人員應該使用int
64bit。 該標准允許它。
如果編譯器開發人員決定堅持使用32位整數,那么通常應該信任他。
也許,在極少數情況下,經過大量的優化工作,你會發現long
工作更好。 然后你可能想要改變。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.