go sync:减少Map中的指针开销

oyjwcjzk  于 2个月前  发布在  Go
关注(0)|答案(2)|浏览(94)

Go 1.9实现的sync.Map非常依赖指针。这会浪费一些CPU(跟踪和缓存这些指针及其地址转换),并且消耗比它可能需要的更稳定的内存(每个条目至少一个指针)。
现在,既然sync.Map已经在标准库中(而不仅仅是x/sync),我们可以利用关于mapinterface{}和/或atomic.Value运行时实现的知识来消除其中的一些指针。
特别是,我们可能可以将readOnly.m字段更改为直接包含一个runtime.hmap变量,而不是指向它的map变量。
我们还可能能够将该Map的元素从*entry更改为entry,因为它们的地址将是稳定的(除非我们解决#19094问题)。对我来说,这是否会给将读写Map提升为只读的过程增加太多复杂性并不明显:特别是,我们需要某种方法来确保没有线程试图更新先前只读Map的条目,这可能需要我们在GC安全点期间仅将读写提升为只读。
最后,我们可能能够直接在entry结构中存储interface{}值,而不是不安全的接口指针,尽管(如atomic.Value所示)更新的同步可能是非常微妙的。
进一步的指针优化可能是可能的;这些只是我能想到的。
我不打算自己立即进行这种优化工作,但我想记录这个想法,以防社区中的其他人有一个激励他们解决这个问题的使用场景。

7fhtutme

7fhtutme1#

我认为解决这个问题需要运行时特定的钩子,或者至少是关于运行时行为的假设代码,这些假设不是语言规范保证的。

yfjy0ee7

yfjy0ee72#

我今天尝试使用atomic.Value来减少一些指针,但最终发现无法保存nil。请参阅https://github.com/golang/go/blob/master/src/sync/map.go#L431C8 -L431C8。意识到支持存储nil的atomic.Value将遇到如何表示已清除的问题。

相关问题