天天看點

go 位址對齊保證

unsafe标準庫包

​func Alignof(variable ArbitraryType) uintptr​

​​。 此函數用來取得一個值在記憶體中的位址對齊保證(address alignment guarantee)。 注意,同一個類型的值做為結構體字段和非結構體字段時位址對齊保證可能是不同的。 當然,這和具體編譯器的實作有關。對于目前的标準編譯器(go 1.18),同一個類型的值做為結構體字段和非結構體字段時的位址對齊保證總是相同的。 ​

​gccgo​

​編譯器對這兩種情形是差別對待的。

package main

import (
  "fmt"
  "unsafe"
)

func main() {
  var x struct {
    a int64
    b bool
    c string
  }
  fmt.Println(unsafe.Alignof(x.a)) //8
  fmt.Println(unsafe.Alignof(x.b)) //1
  fmt.Println(unsafe.Alignof(x.c)) //8
}      

位址對齊保證

為了充分使用​

​CPU​

​​的指令并獲得最佳性能,為給指定類型的值配置設定的記憶體塊(起始)位址必須是一個整數​

​N​

​​的倍數,則​

​N​

​​稱為該類型的值的(記憶體)位址對齊保證,或者簡單的稱為該類型的對齊保證。我們也可以說,這個類型的可尋址值的位址確定是​

​N​

​位元組對齊的。

事實上,每種類型擁有兩個對其保證,一種當它作為其他類型​

​(struct)​

​的字段,另一種是針對其他情況(如當它作為一個變量的聲明,數組元素的類型等等)。我稱前者為類型的字段對齊保證,而稱後者為類型的一般對齊保證。

對于一種類型,我們可以調用​

​unsafe.Algnof(t)​

​​去擷取它的一般對齊保證,其中​

​t​

​​是​

​T​

​​類型的無字段值,也可以調用​

​unsafe.Algnof(x.t)​

​​去擷取它字段的對齊保證,其中​

​x​

​​是一個​

​struct​

​​的值,同時​

​a​

​​是類型​

​T​

​的字段值。

标準庫​

​unsafe​

​中的函數調用總是在編譯期間。