为了账号安全,请及时绑定邮箱和手机立即绑定

为什么 Go 经常将字符串的数据存储在未对齐的地址

为什么 Go 经常将字符串的数据存储在未对齐的地址

Go
函数式编程 2022-05-18 17:03:20
我已经阅读了很多关于内存中值对齐的重要性的内容,因为访问未对齐的地址可能会减慢操作速度,或者显然根本不起作用,具体取决于 CPU 架构(参考https://syslog.ravelin.com/ go-and-memory-layout-6ef30c730d51)。但后来我注意到,在 Go 中实例化一个简单的字符串时,它经常将字符串值存储在未对齐的地址中。这可以通过运行以下代码看到:package mainimport (    "fmt"    "unsafe"    "reflect")func main() {    testString:= "testString"    fmt.Println(fmt.Sprintf("Data is at address %d", ((*reflect.StringHeader)(unsafe.Pointer(&testString))).Data))}在https://play.golang.org/p/d1eX0nP3AgV上运行它时,我不断得到:Data is at address 11403051140305显然不能被4or整除8。有人可以解释一下为什么 Go 将该值存储在一个未对齐的地址中吗?使用对齐的不是更好吗?这仅仅是为了不浪费空间,同时依靠现代 CPU 可以处理它的事实。或者是因为虚拟内存层抽象了物理内存地址,实际上物理地址是正确对齐的?
查看完整描述

1 回答

?
万千封印

TA贡献1891条经验 获得超3个赞

您是对的,32 位值(例如整数)应该在 4 字节边界上对齐,否则访问它可能需要两次内存访问而不是一次。类似地,64 位值应该在 8 字节边界上对齐,尽管在 32 位系统(即 32 条数据线到内存)中,4 字节边界就足够了,因为无论如何都需要两次内存访问。

然而,Go 中字符串的数据实际上是一个字节数组,因此没有对齐要求。如果您在 C 中打印字符串的地址,您会发现同样的事情(出于效率原因,它非常关心对齐)。

一旦你理解了对齐,它就相当简单,但需要大量解释。我在http://devmethodologies.blogspot.com/2013/04/alignment-and-pragma-pack.html上写过它(针对 C 语言)。


查看完整回答
反对 回复 2022-05-18
  • 1 回答
  • 0 关注
  • 98 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信