Skip the reference pool mutex on attach when no decrefs are pending - #6200
Skip the reference pool mutex on attach when no decrefs are pending#6200tobni wants to merge 5 commits into
Conversation
1fa73e7 to
bf64a85
Compare
Merging this PR will not alter performance
|
| Mode | Benchmark | BASE |
HEAD |
Efficiency | |
|---|---|---|---|---|---|
| 🆕 | Simulation | empty_pool_attach |
N/A | 2.7 µs | N/A |
| 🆕 | WallTime | nested_attach_scaling/empty_pool[1] |
N/A | 6 ns | N/A |
| 🆕 | WallTime | nested_attach_scaling/empty_pool[2] |
N/A | 6 ns | N/A |
| 🆕 | WallTime | nested_attach_scaling/empty_pool[4] |
N/A | 10 ns | N/A |
| 🆕 | WallTime | nested_attach_scaling/sparse_pool[1] |
N/A | 6 ns | N/A |
| 🆕 | WallTime | nested_attach_scaling/sparse_pool[2] |
N/A | 7 ns | N/A |
| 🆕 | WallTime | nested_attach_scaling/sparse_pool[4] |
N/A | 10 ns | N/A |
Comparing tobni:pool-dirty-flag (2e7b17b) with main (1ed13a0)
|
The 128 bit conversion benchmarks are the failure can be ignored. |
|
FWIW having a lock-free fast path for a mutex makes sense to me as a general thing to help scaling but I haven't thought deeply about the implications here. |
Good to hear! It is the de-facto bottleneck for pants concurrency model, so I am keen on this issue being resolved. |
davidhewitt
left a comment
There was a problem hiding this comment.
Thanks for the PR! Is it possible to build a benchmark which demonstrates the pathological case here? As per the issue we've flip-flopped on this a fair bit, I'm definitely open to having the complexity if we can prove it's worth it.
| if !self.dirty.load(Ordering::Acquire) { | ||
| return; | ||
| } | ||
| self.dirty.store(false, Ordering::Relaxed); |
There was a problem hiding this comment.
Should this pair use compare_exchange?
There was a problem hiding this comment.
My understanding is that compare_exchange would re-introduce the contention point of every attach becoming a writer. I think it is benign that threads CAN fall through to pending_decrefs turning out empty.
TLDR;
No, I dont think it should.
I am struggling a bit to build a benchmark that codspeed can execute that proves contention is reduced with this change. Would a bench that measures the fastpath be sufficient? Edit: I have become more familiar with codspeed and will push a suggestion of walltime benchmark. This might be a larger maintenance burden than this change warrants, so please scrutinize 8530cd7. |
|
@davidhewitt PTAL |
|
These are aggregate results I net using the pushed benchmark locally. I have an 8 pysical-core machine. empty_pool: ┌────────────────────┬───────┬────────┬───────┐
│ threads │ main │ branch │ ratio │
├────────────────────┼───────┼────────┼───────┤
│ 16 cores │ │ │ │
├────────────────────┼───────┼────────┼───────┤
│ 1 │ 104.0 │ 374.0 │ 3.6× │
├────────────────────┼───────┼────────┼───────┤
│ 2 │ 35.6 │ 725.9 │ 20.4× │
├────────────────────┼───────┼────────┼───────┤
│ 4 │ 26.3 │ 1269.1 │ 48.3× │
├────────────────────┼───────┼────────┼───────┤
│ 2 cores │ │ │ │
├────────────────────┼───────┼────────┼───────┤
│ 1 │ 103.9 │ 373.1 │ 3.6× │
├────────────────────┼───────┼────────┼───────┤
│ 2 │ 35.6 │ 553.0 │ 15.5× │
├────────────────────┼───────┼────────┼───────┤
│ 4 │ 35.0 │ 606.0 │ 17.3× │
└────────────────────┴───────┴────────┴───────┘sparse_pool is ~ equivalent |
|
@davidhewitt I feel like we used to have this, and then it got removed at some point, do you remember the history? Am I mixing this up with something else? |
I did some digging and documented my archeology findings in #6199. I believe that illuminates the history. Edit: |
Runners have 2 cores.
Closes #6199.