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

Secret Connection: Remove sync.Pool, and put those buffers in the connection struct #3197

Open
Tracked by #3053
ValarDragon opened this issue Jun 6, 2024 · 4 comments
Labels
enhancement New feature or request p2p

Comments

@ValarDragon
Copy link
Collaborator

Feature Request

Summary

In secret connection we use sync.Pool's for some 1024 byte buffers. However these buffers are only ever needed locally within the same thread, so this is a wasted synchronization primitive that does cost us. All reads and writes in secret connection are under a mutex, so we should just make a new buffer in each secret conn struct.

Impact is ~8% of the current secret connection read time (Get and Put in following pprof):
image

Problem Definition

Slight speedup to secret conn

@ValarDragon ValarDragon added enhancement New feature or request needs-triage This issue/PR has not yet been triaged by the team. labels Jun 6, 2024
@cason cason added the p2p label Jun 11, 2024
@cason
Copy link
Contributor

cason commented Jun 11, 2024

The problem is that Read() and Write() are public methods. So while we know that the p2p connection only uses them in a single thread, the implementation is more generic.

Actually, we have other mutexes in those methods that are based on the same assumption. And this is because it implements generic Go interfaces that assume that Read() and Write() can be called in parallel.

@cason cason removed the needs-triage This issue/PR has not yet been triaged by the team. label Jun 11, 2024
@ValarDragon
Copy link
Collaborator Author

Thats not what I mean, the Read method itself already has the mutex! So these buffers would already be mutex protected

@cason
Copy link
Contributor

cason commented Jun 19, 2024

They are protected by different mutexes:

func (sc *SecretConnection) Read(data []byte) (n int, err error) {
sc.recvMtx.Lock()
defer sc.recvMtx.Unlock()

func (sc *SecretConnection) Write(data []byte) (n int, err error) {
sc.sendMtx.Lock()
defer sc.sendMtx.Unlock()

We use the pool to share buffers between readers and writers...

@cason
Copy link
Contributor

cason commented Jun 19, 2024

What we can have, to reduce contention, are two unsynchronized pools, one for reads, another for writes.

By the way, we import libp2p for this buffer pool :D

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request p2p
Projects
None yet
Development

No branches or pull requests

2 participants