Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

sync: reduce pointer overhead in Map #21031

Open
bcmills opened this issue Jul 16, 2017 · 0 comments

Comments

@bcmills
Copy link
Member

commented Jul 16, 2017

The Go 1.9 implementation of sync.Map is very pointer-heavy. That wastes a bit of CPU (following and caching those pointers and their address translations) and also consumes more steady-state memory than it potentially needs to (by at least one pointer per entry).

Now that sync.Map is in the standard library (instead of just x/sync), we can potentially make use of knowledge about the runtime implementations of map, interface{} and/or atomic.Value to flatten out some of those pointers.

In particular we can probably change the readOnly.m field to contain a runtime.hmap directly instead of a map variable that points to it.

We may also be able to change the elements of that map from *entry to entry, since their addresses will be stable (unless we address #19094). It's not obvious to me whether that would add too much complexity to the process of promoting the read-write map to read-only (which is currently just an atomic store): in particular, we would need some way to ensure that no thread is trying to update the entries of the previous read-only map, which might require that we only promote read-write to read-only during a GC safe-point.

Finally, we may be able to store interface{} values directly in the entry struct rather than unsafe-pointers-to-interfaces, although (as atomic.Value demonstrates) the synchronization for updates may be very subtle.

Further pointer optimizations may be possible; those are just the ones I can think of.


I don't intend to do this optimization work myself any time soon, but I wanted to document this idea in case someone else in the community has a use-case that motivates them to address it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
3 participants
You can’t perform that action at this time.