Go內(nèi)存對(duì)齊對(duì)性能的影響
CPU 訪問(wèn)內(nèi)存時(shí)粟判,并不是逐個(gè)字節(jié)訪問(wèn)肖揣,而是以字長(zhǎng)為單位。32位CPU的字長(zhǎng)是4字節(jié)浮入,64位CPU的字長(zhǎng)是8字節(jié)。
CPU 始終以字長(zhǎng)訪問(wèn)內(nèi)存羊异,如果不進(jìn)行內(nèi)存對(duì)齊事秀,很可能增加 CPU 訪問(wèn)內(nèi)存的次數(shù)。
-
unsafe.Sizeof
: 返回?cái)?shù)據(jù)類型需要占用的字節(jié)數(shù) -
unsafe.Alignof
: 返回?cái)?shù)據(jù)類型的對(duì)齊系數(shù)
type Args struct {
num1 int // int占8字節(jié)
num2 int // int占8字節(jié)
}
type Flag struct {
num1 int16 // int16占2字節(jié)
num2 int32 // int32占4字節(jié)
}
func main() {
fmt.Println(unsafe.Sizeof(Args{}))
fmt.Println(unsafe.Sizeof(Flag{}))
}
-
Args
由 2 個(gè)int
類型的字段構(gòu)成野舶,在 64位機(jī)器上易迹,一個(gè)int
占 8 字節(jié),因此存儲(chǔ)一個(gè)Args
實(shí)例需要 16 字節(jié)平道。 -
Flag
由一個(gè)int32
和 一個(gè)int16
的字段構(gòu)成睹欲,成員變量占據(jù)的字節(jié)數(shù)為 4+2 = 6,但是unsafe.Sizeof
返回的結(jié)果為 8 字節(jié)一屋,多出來(lái)的 2 字節(jié)是內(nèi)存對(duì)齊的結(jié)果窘疮。
對(duì)齊補(bǔ)證
- 對(duì)于任意類型的變量 x ,
unsafe.Alignof(x)
至少為 1冀墨。 - 對(duì)于 struct 結(jié)構(gòu)體類型的變量 x闸衫,計(jì)算 x 每一個(gè)字段 f 的
unsafe.Alignof(x.f)
,unsafe.Alignof(x)
等于其中的最大值诽嘉。 - 對(duì)于 array 數(shù)組類型的變量 x蔚出,
unsafe.Alignof(x)
等于構(gòu)成數(shù)組的元素類型的對(duì)齊倍數(shù)。