Golang Go语言中cacheline 填充的意义

这种填充方式能解决 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
}

Golang Go语言中cacheline 填充的意义

更多关于Golang Go语言中cacheline 填充的意义的实战教程也可以访问 https://www.itying.com/category-94-b0.html

11 回复

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

更多关于Golang Go语言中cacheline 填充的意义的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


啊,请忽略上条

struct PaddedStruct {
int a;
char cache_line_pad[64];
int b;
};

这个结构体的 a 会不会和另一个结构体的尾部合成一个 cache 块了

#4 当然会,和 struct 无关,只关心是否两个变量是否同在一个 Cache Block 里面

我测出来了,性能差了 3 倍以上,https://go.dev/play/p/WF-CoUIe4bd

goos: windows
goarch: amd64
pkg: btest
cpu: 11th Gen Intel® Core™ 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

嗯,我的意思是,要解决一个 struct 中的变量和其他 struct 中的变量造成 false sharing ,是不是应该在那个变量的前后都加上 cachelinepad ,只在前或后一端加都没法避免,我看很多的文章讲避免 false sharing ,都拿一端填充的例子讲,所以比较疑惑

#8 理论上是的,但是这种优化不是绝对的,把高频操作的变量分开就可以了

好的,多谢

在Golang(Go语言)中,cacheline填充是一种优化技术,其目的在于减少CPU缓存争用(也称为缓存行冲突)和提升程序的并发性能。

现代CPU为了提高内存访问速度,会将数据保存在多级缓存中。缓存行(cacheline)是缓存中最小的数据传输单元,通常为64字节。当多个线程或核心同时访问相邻内存地址时,它们可能会操作同一个缓存行,导致缓存行失效和重新加载,这种现象称为缓存行冲突。

在Go语言中,特别是在高并发场景下,如果多个goroutine访问或修改共享数据的内存区域,就可能引发缓存行冲突。这会导致CPU缓存命中率下降,内存访问延迟增加,从而降低程序的整体性能。

为了解决这一问题,开发者可以使用cacheline填充技术。具体做法是在共享数据结构之间插入足够大的内存间隔(通常是多个缓存行大小),以确保不同的数据项位于不同的缓存行上。这样,即使多个goroutine同时访问这些数据,也不会引发缓存行冲突,从而提高了缓存命中率和程序性能。

值得注意的是,cacheline填充虽然能带来性能提升,但也会增加内存占用。因此,在使用时需要权衡性能提升和内存开销之间的关系。此外,cacheline填充的效果还取决于具体的硬件架构和程序运行时的行为,因此在实际应用中可能需要进行实验和调整以达到最佳效果。

回到顶部