cacheline 填充的意义

2022-09-02 21:20:28 +08:00
 docxs

这种填充方式能解决 false sharing 吗,

type PaddedStruct struct {
    _ CacheLinePad
    n int
}

type CacheLinePad struct {
    _ [CacheLinePadSize]byte
}

const CacheLinePadSize = 64

CacheLinePad 后面的字段,是怎么避免和其他结构体不共享一个 Cache 块了,把 CacheLinePad 放在第一个字段,只能避免和它前面的数据不在一个 cache 块吧,是不是应该这样

type PaddedStruct struct {
    _ CacheLinePad
    n int
    _ CacheLinePad
}
1388 次点击
所在节点    Go 编程语言
10 条回复
1423
2022-09-02 23:19:51 +08:00
On ARM, 386, and 32-bit MIPS, ........ The first word in an allocated struct, array, or slice; in a global variable; or in a local variable can be relied upon to be 64-bit aligned.

https://pkg.go.dev/sync/atomic
1423
2022-09-02 23:22:44 +08:00
啊,请忽略上条
qwe678
2022-09-03 12:38:11 +08:00
struct PaddedStruct {
int a;
char cache_line_pad[64];
int b;
};
docxs
2022-09-03 16:38:46 +08:00
@qwe678 这个结构体的 a 会不会和另一个结构体的尾部合成一个 cache 块了
lysS
2022-09-04 11:15:30 +08:00
@docxs #4 当然会,和 struct 无关,只关心是否两个变量是否同在一个 Cache Block 里面
lysS
2022-09-04 11:30:28 +08:00
我测出来了,性能差了 3 倍以上,https://go.dev/play/p/WF-CoUIe4bd

goos: windows
goarch: amd64
pkg: btest
cpu: 11th Gen Intel(R) Core(TM) i5-11320H @ 3.20GHz
BenchmarkD1
BenchmarkD1-8
582 1844166 ns/op 66 B/op 3 allocs/op
BenchmarkD2
BenchmarkD2-8
2710 387049 ns/op 59 B/op 3 allocs/op
BenchmarkC1
BenchmarkC1-8
583 1974648 ns/op 53 B/op 2 allocs/op
BenchmarkC2
BenchmarkC2-8
2938 396749 ns/op 42 B/op 2 allocs/op
PASS
ok btest 4.985s
lysS
2022-09-04 11:35:29 +08:00
docxs
2022-09-04 15:54:08 +08:00
@lysS 嗯,我的意思是,要解决一个 struct 中的变量和其他 struct 中的变量造成 false sharing ,是不是应该在那个变量的前后都加上 cachelinepad ,只在前或后一端加都没法避免,我看很多的文章讲避免 false sharing ,都拿一端填充的例子讲,所以比较疑惑
lysS
2022-09-04 18:31:54 +08:00
@docxs #8 理论上是的,但是这种优化不是绝对的,把高频操作的变量分开就可以了
docxs
2022-09-04 19:26:17 +08:00
@lysS 好的,多谢

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/877343

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX