From a173b002910266ffa5d527ee353f6754e62d7720 Mon Sep 17 00:00:00 2001 From: Daniel Han Date: Sat, 4 Jul 2026 07:40:34 +0000 Subject: [PATCH] Pin the sd.cpp CPU backend to physical cores threads = None let sd.cpp default to the logical-core count. The diffusion CPU path is compute-bound GGML matmuls, where oversubscribing hyperthreads adds scheduling contention without extra throughput, so both the persistent server and the one-shot sd-cli now pass cpu_count // 2 (min 1, fallback 8). --- .../backend/core/inference/sd_cpp_backend.py | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/studio/backend/core/inference/sd_cpp_backend.py b/studio/backend/core/inference/sd_cpp_backend.py index d8cb21d409..45ecee64f5 100644 --- a/studio/backend/core/inference/sd_cpp_backend.py +++ b/studio/backend/core/inference/sd_cpp_backend.py @@ -89,6 +89,17 @@ _MAX_SERVER_BATCH = 8 _SERVER_PER_IMAGE_TIMEOUT_S = 1800.0 +def _default_threads() -> int: + """Physical-core thread count for the sd.cpp CPU backend. + + ``threads = None`` lets sd.cpp pick its own default, which is the logical-core + count (all hyperthreads). For the compute-bound GGML matmuls the diffusion CPU + path runs, oversubscribing the hyperthreads adds scheduling contention without + extra throughput, so pin to physical cores (``cpu_count // 2``) instead. Falls + back to 8 when the count is unknown, and clamps to at least 1.""" + return max(1, (os.cpu_count() or 8) // 2) + + def _server_binary_runnable(binary: str) -> bool: """Best-effort probe that ``binary`` can actually execute (not just exist). @@ -531,7 +542,9 @@ class SdCppDiffusionBackend: vae_format = fam.sd_cpp_vae_format, offload = list(offload), native_speed = native_speed, - threads = None, + # Pin the CPU backend to physical cores; sd.cpp's own + # default oversubscribes hyperthreads (see _default_threads). + threads = _default_threads(), ) except SdCppCancelled: # Startup was aborted by an unload / superseding load: stop the @@ -568,7 +581,9 @@ class SdCppDiffusionBackend: vae_format = fam.sd_cpp_vae_format, native_speed = native_speed, offload_flags = offload, - threads = None, + # One-shot sd-cli reads this per generation (state.threads); pin to + # physical cores for the same reason as the server (see _default_threads). + threads = _default_threads(), sampling_method = fam.sd_cpp_sampling_method, flow_shift = fam.sd_cpp_flow_shift, server = server,