Skip to content

perf(serverless): probe CPU info only for debugger - #631

Closed
deanq wants to merge 1 commit into
mainfrom
deanq/sls-814-lazy-cpuinfo
Closed

deanq wants to merge 1 commit into
mainfrom
deanq/sls-814-lazy-cpuinfo

Conversation

@deanq

@deanq deanq commented Oct 19, 2026

Copy link
Copy Markdown
Member

Summary

rp_debugger.py ran cpuinfo.get_cpu_info() at import. The worker imports rp_debugger on every start (worker → rp_local → rp_job → rp_debugger). On x86, py-cpuinfo measures clock speed in a child process around a fixed sleep(1) (CPUID.get_raw_hz), so every cold start paid about 1.2s for a value only used with --rp_debugger.

  • The processor is looked up lazily in a cached _get_processor(), called from get_debugger_output()
  • cpuinfo is imported inside that function; importing it also spawns a subprocess (platform.architecture() runs file)
  • rp_debugger.PROCESSOR still works for existing callers, resolved lazily through a module __getattr__

With --rp_debugger enabled, the probe moves to the first job and runs once per process.

Impact

Measured on a real RTX 4090 serverless worker (AMD EPYC 7B13, 128 CPUs):

Time
cpuinfo.get_cpu_info() 1169 / 1171 / 1172 ms
Generated handler loaded → first worker-start fitness check, 2.0.0rc1 1459 / 1469 ms
Same span, this branch 536 ms

"cpuinfo" in sys.modules was False inside the handler on this branch. On macOS arm64 the probe takes about 40ms because py-cpuinfo skips the x86 CPUID path, so local testing does not show the problem.

Test plan

  • New: importing the module does not call get_cpu_info (fails on main)
  • New: importing the module does not load cpuinfo, checked in a fresh interpreter (fails on main)
  • New: debugger output reports the processor, looked up at call time (fails on main)
  • New: the lookup is cached across calls
  • KeyError fallback and lazy PROCESSOR attribute
  • make quality-check: 1484 passed, 91.67% coverage
  • Real GPU worker with this branch bundled: start gap 1459ms → 536ms

Linear: SLS-814

rp_debugger called cpuinfo.get_cpu_info() at import. On x86,
py-cpuinfo measures clock speed in a child process around a fixed
sleep(1), and the worker imports rp_debugger on every start, so
every cold start paid about 1.17s for a value used only with
--rp_debugger.

- Probe lazily in a cached _get_processor(), called from
  get_debugger_output()
- Import cpuinfo inside the function; its import also spawns a
  subprocess
- Keep rp_debugger.PROCESSOR working via module __getattr__

Real GPU worker (RTX 4090): handler loaded -> first worker-start
fitness check went from 1459/1469ms to 536ms.

Linear: SLS-814
Comment on lines +50 to +51
"import sys; import runpod.serverless.utils.rp_debugger; "
"print('cpuinfo' in sys.modules)",
Comment on lines +50 to +51
"import sys; import runpod.serverless.utils.rp_debugger; "
"print('cpuinfo' in sys.modules)",

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 Approval recommended

The focused changes preserve debugger behavior, include relevant regression coverage, and have no unresolved findings.

No open issues 🎉

What changed in this PR

Reduces serverless worker cold-start overhead by deferring CPU detection until debugger information is requested.

Changes:

  • Lazily imports cpuinfo and caches the processor lookup.
  • Preserves access to rp_debugger.PROCESSOR through a lazy module attribute.
  • Adds regression tests for deferred loading, caching, processor reporting, and fallback behavior.
File Description
tests/​test_serverless/​test_utils/​test_debugger.py Tests lazy CPU detection and compatibility behavior.
runpod/​serverless/​utils/​rp_debugger.py Defers CPU detection and caches its result.

Review effort: Balanced

@deanq

deanq commented Oct 19, 2026

Copy link
Copy Markdown
Member Author

Closing as a duplicate of #629, which makes the same change (lazy, cached CPU probe off the worker import path). The real-worker measurements from this PR are now in #629's description.

@deanq deanq closed this Oct 19, 2026
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.

3 participants