Skip to content

Avoid RMWs when polling empty remote queues - #2180

Merged
ericniebler merged 8 commits into
NVIDIA:mainfrom
fallintoplace:perf/static-thread-pool-empty-remote-poll
Aug 15, 2026
Merged

Avoid RMWs when polling empty remote queues#2180
ericniebler merged 8 commits into
NVIDIA:mainfrom
fallintoplace:perf/static-thread-pool-empty-remote-poll

Conversation

@fallintoplace

@fallintoplace fallintoplace commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

Summary

  • skip the CAS dequeue for remote queue shards observed empty
  • keep the CAS path for nonempty shards
  • force the dequeue before a worker goes to sleep
  • keep this scoped to static_thread_pool remote polling
  • cover shared and per-thread producer schedulers in tests

Each worker walks every producer shard when checking for remote work. The current empty path performs a compare-exchange from null to null on every shard, taking exclusive ownership of cache lines only to discover that no work is present.

Before sleeping, the worker still does a real dequeue across the remote queues. This keeps the empty check as a speculative optimization while retaining the sleep-boundary safety check.

Benchmark on current HEAD

Equivalent isolated empty remote-queue-list polling on an Apple M1 Pro, optimized build. The isolated numbers were measured before the test and benchmark cleanup commits. The production polling path is unchanged by those cleanup commits. The baseline forces the existing CAS dequeue for every shard; this branch first probes empty() and only dequeues nonempty shards. Values are median nanoseconds per complete list poll.

Dormant producer shards Current This branch Speedup
0 7.03 ns 0.99 ns 7.1x
8 21.33 ns 4.68 ns 4.6x
32 79.22 ns 25.18 ns 3.1x
128 298.36 ns 154.67 ns 1.9x

End-to-end benchmark rerun

Reran build/examples/example.benchmark.static_thread_pool on an Apple M1 Pro with the Release build.

  • Base: origin/main at 3a836a97
  • PR: 16f3342f
  • Command: ./build/examples/example.benchmark.static_thread_pool <threads>
  • 10,000,000 schedules per round
  • 100 rounds with one warmup round
Workers / producer threads origin/main This branch Change
1 19.2M schedules/s 20.3M schedules/s +5.7%
4 13.5M schedules/s 14.0M schedules/s +3.7%

This is a steady-state scheduling benchmark. It does not measure enqueue-to-start latency or repeated sleep/wake bursts.

Testing

  • cmake --build build --target test.exec -j2
  • ctest --test-dir build -R 'static_thread_pool' --output-on-failure (14/14 passed)
  • Relacy remote-poll model: 50,000 iterations under x86_64 emulation
  • Stress coverage for both a shared scheduler and per-thread producer schedulers

@copy-pr-bot

copy-pr-bot Bot commented Aug 10, 2026

Copy link
Copy Markdown

This pull request requires additional validation before any workflows can run on NVIDIA's runners.

Pull request vetters can view their responsibilities here.

Contributors can view more details about this message here.

@fallintoplace fallintoplace reopened this Aug 14, 2026
@fallintoplace
fallintoplace marked this pull request as ready for review August 14, 2026 11:29
@fallintoplace
fallintoplace force-pushed the perf/static-thread-pool-empty-remote-poll branch from 452a1cc to 7885761 Compare August 14, 2026 13:23
@ericniebler

Copy link
Copy Markdown
Collaborator

/ok to test 361048d

@ericniebler

Copy link
Copy Markdown
Collaborator

/ok to test 349c692

@ericniebler

Copy link
Copy Markdown
Collaborator

/ok to test 16f3342

@ericniebler

Copy link
Copy Markdown
Collaborator

/ok to test 6578d3a

@ericniebler
ericniebler merged commit 7735228 into NVIDIA:main Aug 15, 2026
38 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants