首页 > 其他分享 >go 地址对齐保证

go 地址对齐保证

时间:2022-08-22 14:11:27浏览次数:61  
标签:fmt unsafe 类型 地址 保证 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)去获取它的一般对齐保证,其中tT类型的无字段值,也可以调用unsafe.Algnof(x.t)去获取它字段的对齐保证,其中x是一个struct的值,同时a是类型T的字段值。

标准库unsafe中的函数调用总是在编译期间。

在运行期间,对于类型T的值,我们可以调用reflect.TypeOf(t).Align()去获取类型T的一般对齐保证,也可以调用reflect.TypeOf(t).FieldAlign()去获取类型T字段的一般对齐保证。

标签:fmt,unsafe,类型,地址,保证,go,对齐
From: https://www.cnblogs.com/niuben/p/16612611.html

相关文章