-
Notifications
You must be signed in to change notification settings - Fork 17.7k
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: per-cpu storage #8281
Comments
Yes. I want more complex objects than a simple integer counter, with custom aggregation logic. I assume acquire fetches an instance of T from the cpu local(?); release returns the instance to the current cpu local. Since a goroutine can be moved to another cpu, release may return the instance to a different cpu local. If my guess is correct, there could be multiple T instances corresponding to a single cpu at a certain point. Do you expect foreach can work as flush mechanism of Ts as well? |
Yes, there can more instances than CPUs (we can't pin arbitrary user code to CPU). I would do something like at most 2*NCPU objects. I don't like the idea of foreach being a flush. First it's not obvious. Second foreach may not be called at all. Does it work for you if we just have at most 2*NCPU objects? |
I can't see any connection between async log flushing and per-CPU storage. Separately, I think that per-cpu storage is probably too low-level a primitive. It's defining an implementation instead of a high-level goal. For example, the high-level goal of sync.Pool is to reclaim memory kept in caches. It happens that we built a very fast sync.Pool by using per-CPU storage underneath, but the per-CPU storage is not the point. I suspect that the real thing you need is a better high-level target than per-CPU storage. Status changed to Thinking. |
For logging, I'd like to have an interface that lets multiple goroutines write lines of text simultaneously while another goroutines consumes those lines, e.g., to flush them off to disk or the network. An implementation might provide per-CPU buffers to reduce contention. Hana's stats counters would be a different interface that might also leverage per-CPU counters plus some aggregation. In both cases, you have many writers and some aggregation in the consumer. |
Agree that this is not a good fit for logging - need api to discourage such use. I expect the buffered channel perf improvement work to help for this case. What about the stat collection application? We've tried a channel based implementation (let many goroutines send stat update through channel and have a receiver goroutine that updates the stats.) and a mutex-based implementation (let many goroutines fight for a single mutex to update the stats). None was satisfactory. |
"buffered channel perf improvement work" is deferred, see: https://groups.google.com/d/msg/golang-dev/0IElw_BbTrk/FtV82Tr3S00J Your use case can potentially provide the necessary justification. You can compare performance of chan-based solution with and without the change. |
after listening to Prometheus talk at gophercon, i remembered this issue (exactly same motivation) and I wonder if per-cpu storage can help reducing lock contention. |
(It turns out that if you're willing to abuse finalizers, you can mostly implement this API today in terms of On the other hand, the use of |
Hmm... I suppose that having Perhaps it would be clearer to structure the per-thread pool and the thread-locking behavior as separate APIs: thread.Locked(func() {
v := pool.Get()
doSomethingExclusiveWith(v)
}) ( Unfortunately, moving the thread-locking to a separate API makes It seems simpler to only provide a per-thread API that doesn't guarantee exclusiveness. |
The text was updated successfully, but these errors were encountered: