优化golang中的数据结构/字对齐填充

时间:2016-08-21 11:10:52

标签: go struct padding memory-alignment

与我在C ++中学到的相似,我认为填充会导致两个结构的实例大小不同。

amd64
16
24

输出:

{{1}}
  • 定义struct成员时是否遵循经验法则? (如类型大小的升序/降序)
  • 我们可以通过编译时优化,可以自动处理吗?
  • 或者我根本不应该担心这个?

3 个答案:

答案 0 :(得分:12)

目前还没有编译时优化;在x64上将值填充为8个字节。

您可以手动排列结构以最佳地利用空间;通常从较大的类型变为较小的类型;例如,8个连续字节字段将仅使用8个字节,但是单个字节将填充为8字节对齐,请考虑以下情况:https://play.golang.org/p/0qsgpuAHHp

package main

import (
    "fmt"
    "unsafe"
)

type Compact struct {
    a, b                   uint64
    c, d, e, f, g, h, i, j byte
}

// Larger memory footprint than "Compact" - but less fields!
type Inefficient struct {
    a uint64
    b byte
    c uint64
    d byte
}

func main() {
    newCompact := new(Compact)
    fmt.Println(unsafe.Sizeof(*newCompact))
    newInefficient := new(Inefficient)
    fmt.Println(unsafe.Sizeof(*newInefficient))
}

如果你考虑到这一点;您可以优化结构的内存占用。

答案 1 :(得分:9)

  

或者我根本不应该担心这个?

是的,你应该 这也称为mechanical sympathy(请参阅此Go Time podcast episode),因此它还取决于您要编译的硬件架构。

见图:

  

Go切片中的值是16字节对齐的。它们不是32字节对齐的   Go指针是字节对齐的。

答案 2 :(得分:2)

这取决于您正在开发的应用程序类型以及这些结构的用法。如果应用程序需要满足某些内存/性能标准,则您绝对应该关注内存的对齐方式和填充,但不仅仅是-一篇不错的文章https://www.usenix.org/legacy/publications/library/proceedings/als00/2000papers/papers/full_papers/sears/sears_html/index.html着重介绍了最佳CPU缓存使用率的主题以及结构布局与性能之间的关联。突出显示缓存行对齐,错误共享等。

还有一个不错的golang工具https://github.com/1pkg/gopium,可帮助自动执行这些优化,并进行检查!