我們閱讀了每一份回饋,並非常認真地對待您的意見。
路由 navigator.hardwareConcurrency、os.availableParallelism() 和 bun.getThreadCount() 透過 WTF::numberOfProcessorCores(),在 Linux 上現在是 min(sysconf(_SC_NPROCESSORS_ONLN), sched_getaffinity count, cgroup CPU quota)。
在 docker run --cpus=2 (或 k8s resources.limits.cpu) 下,核心會設定 CFS 頻寬配額,而不是 cpuset mask。sysconf 和 sched_getaffinity 都仍然回報主機核心數,因此在 96 核心的主機上,Bun 會為線程池、JSC 並行 GC 標記器和 JIT 工作程序創建約 96 個線程。這些線程會在幾毫秒的實際時間內耗盡 200ms/100ms 的配額,並在該週期的剩餘時間內導致整個 cgroup 被調度程序暫停 — 鋸齒狀延遲,nr_throttled 數值上升,GC 在收集過程中卡住。
Node 回報 2 (libuv 讀取 cpu.max);Bun 回報 96。
一個函數現在為 JSC GC/JIT 定義大小、navigator.hardwareConcurrency、os.availableParallelism() 和 Bun 的內部線程池提供資訊。
❌ @Jarred-Sumner,您的提交 1526b00 在 Build #43430 中有 3 項失敗 (所有失敗):
這會在您的 bun-28801 可執行檔中安裝 PR 的本地版本,因此您可以運行:
中央化的 CPU 核心檢測:添加了 Zig/C++ 綁定以暴露 WTF::numberOfProcessorCores(),用該調用替換了特定平台的計數邏輯,並更新了線程和 Node OS CPU 初始化以使用新的 API。WebKit 預編譯版本哈希已更新。
✏️ 提示:您可以在設定中配置自己的自訂預合併檢查。
有一個問題隱藏此評論。
將顯示原因以向他人描述此評論。了解更多。
我先前評論中提到的 os.cpus() 陣列突變錯誤已在當前代碼中修復 — lazyCpus 正確使用了 hostCpuCount (來自 sysconf,即主機 CPU 計數) 而不是 navigator.hardwareConcurrency,因此在 populate() 之前和之後陣列長度保持一致。話雖如此,此 PR 觸及了線程池大小、JSC GC/JIT 工作程序計數,並具有跨儲存庫的 WebKit 依賴項,因此應由人工審查架構決策。
此 PR 將 navigator.hardwareConcurrency、os.availableParallelism() 和 bun.getThreadCount() 路由到 WTF::numberOfProcessorCores(),在 Linux 上,一旦配套的 WebKit PR 合併,它將變為 min(sysconf, sched_getaffinity, cgroup cpu.max)。Bun 端的變更涉及 7 個文件:Zig/C++ 中的新 WTF 綁定、更新的 ZigGlobalObject.cpp、一個新的 bun_sysconf__SC_NPROCESSORS_ONLN() 助手,以及 os.ts/node_os.zig 的變更。
我先前行內評論指出 lazyCpus 從 navigator.hardwareConcurrency (cgroup 限制) 調整陣列大小,而原生 cpus() 綁定返回主機 CPU,導致 populate() 時發生靜默長度突變。當前代碼已解決此問題:lazyCpus 接收 hostCpuCount (來自 bun_sysconf__SC_NPROCESSORS_ONLN(),即原始 sysconf 值) 並使用它來確定陣列大小。雙方現在對主機 CPU 計數達成一致。我先前的錯誤評論描述的是當前代碼中已不存在的狀態。
沒有安全風險。這僅僅是關於 CPU 計數檢測和線程池大小設定。
高 — 這觸及了 getThreadCount(),它影響 Bun 內部線程池的大小設定,以及 navigator.hardwareConcurrency,它影響 JSC GC 並行標記器和 JIT 工作程序計數。出錯(計數過少或過多)會直接影響效能。WebKit 的依賴項也意味著 cgroup 行為僅在該單獨的 PR 合併且供應的引用被更新後才會激活 — 這是一個非瑣碎的跨儲存庫協調要求。
PR 描述中提到 os.cpus().length 變為 cgroup 限制,這與實際代碼不一致,因為實際代碼使用主機 CPU 計數來獲取 hostCpuCount。文檔與實施之間的這種差異是一個小問題,但值得澄清。自動獵殺系統沒有發現任何錯誤。該變更描述良好,並解決了實際的容器 CPU 節流問題。
我們故意不在 K8S 上運行我們的負載,而不設定 CPU 限制(以避免 CFS 節流或突發選項),僅依賴 CPU 請求。這意味著 cgroup 配額是無限的,因此 WTF::numberOfProcessorCores() 仍然回報完整的主機核心數 — 從核心的角度來看這是正確的,但並非我們實際想要的。
今天我可以設定 UV_THREADPOOL_SIZE 來限制 Bun 的線程池,但這只會影響 getThreadCount()。它不會影響 navigator.hardwareConcurrency / os.availableParallelism(),這意味著依賴 availableParallelism() 的庫仍然會過度配置。
我正在考慮引入一個新的環境變量,例如 ACTIVE_PROCESSOR_COUNT,它將影響:
如果您認為這合理,我很樂意提交一個 PR。
成功合併此拉取請求可能會關閉這些問題。