後端工坊 2026 年 5 月 17 日

2026-05-17 — image-rs blur 5.9 倍加速、Bun Rust 移植 AI 代碼疑慮、OxCaml 資料競爭自由

primary=https://apas.tel/blog/optimizing-image-rs-blur primary=https://en.liujiacai.net/2026/05/16/bun-rust-port/ primary=https://kcsrk.info/ocaml/oxcaml/x-ocaml/blogging/2026/05/07/data-race-freedom-in-oxcaml/

image-rs 的 fast_blur 加速 5.9 倍:整數累積器與倒數乘法

apas.tel · 2026-05-16

image-rs 的 fast_blur 函式實作了以三次連續 box blur 近似 Gaussian blur 的演算法(sigma 無關的 O(1) 複雜度)。2026 年 5 月的優化在不改變輸出品質的情況下,將執行時間從 51ms 壓縮至約 9ms(σ=7,1920×1080 RGBA),相當於影片處理從 19 FPS 提升至 120 FPS。

原本的問題

原始實作的熱路徑將每個 u8 子像素轉換為 f32、進行浮點數累積,再透過 roundf 轉換回來。火焰圖分析顯示三個主要瓶頸:

  • roundf:27% 執行時間
  • to_f32 類型轉換:22% 執行時間
  • min/max 操作:20% 執行時間

優化一:u32 整數累積器

將浮點累積改為 u32 整數累積,以整數除法取代 roundf

// 原始:浮點路徑
result = rounding_saturating_mul(sum as f32, inv_kernel);

// 新版:整數路徑
result = ((sum + kernel_size / 2) / kernel_size) as u8;

u32 的上限足以安全累積 blur kernel 值(u32::MAX / 255 ≈ 1680 萬),無溢位風險。此優化帶來 ~1.83 倍加速,消除所有 roundf 與浮點轉換開銷。

優化二:倒數乘法取代除法

基於 Granlund & Montgomery(1994)研究,以預計算倒數取代每像素的整數除法。除法需要 20–30 個 CPU cycle 且阻塞 pipeline;乘法加位移只需 3–4 個 cycle:

struct U8Weight {
    reciprocal:    u32,  // ceil(2^32 / kernel_size)
    rounding_bias: u32,  // kernel_size / 2
}

// 除法替換:
((sum as u64 * reciprocal as u64) >> 32) as u8

此步驟帶來 ~3.2 倍的額外加速

基準測試結果

Sigma優化前優化後加速
σ=351.1 ms8.6 ms5.9×
σ=751.5 ms9.0 ms5.7×
σ=5052.2 ms10.2 ms5.1×

最終實作透過 BlurAccumulator trait 支援多像素類型:u8 使用 u32 快速路徑,其他類型(u16、f32、f64)退回 f32 累積器,在不引入執行時分支的情況下維持泛型設計

原始來源:apas.tel


Bun 的 Rust 移植:6,755 個 AI 生成的 commit 帶來的工程疑慮

Jia-Cai Liu Blog · 2026-05-16

Bun JavaScript runtime 完成了從 Zig 到 Rust 的全面移植,6,755 個 commit 在六天內合入主幹,代碼幾乎全由 Claude 生成並由 Claude 審查。作者 Liu Jia-Cai 分析這次移植的技術背景,以及以 AI 生成代碼為主要生產基礎帶來的長期隱患。

移植的動機

Bun 原始的 Zig 代碼庫累積了 use-after-free、double-free 與錯誤路徑記憶體洩漏等問題。Liu 認為這反映的是語言與團隊文化之間的結構性不匹配:Bun 的快速迭代文化與 Zig 要求精細手動記憶體管理之間存在根本張力。Rust 編譯器的靜態保證讓團隊在快速迭代時免於記憶體安全問題,這是移植的核心邏輯。

技術隱患

Liu 指出 AI 代碼翻譯可以在局部達到語意等價,但無法保證跨函式的全域不變量(global invariants)——那些沒有寫進測試、卻隱含在設計意圖中的系統約束。測試套件驗證的是已知行為在已知路徑上的正確性,對錯誤處理邊界條件與全域系統不變量的覆蓋存在固有局限。

六天內合入、無人工完整審查的 6,755 個 commit,意味著這個代碼庫的可調試性(debuggability)存疑:未來發生線上事件時,工程師需要理解並修改一個從未被人類深度閱讀的代碼庫。

預測

Liu 預測短期穩定性因測試覆蓋率與金絲雀部署而得以維持,但長期的結構性風險在於:AI 生成的生產代碼在技術上合規,卻缺乏人類理解這個基礎,使工程組織在未來複雜調試情境下面臨不確定性。

原始來源:Jia-Cai Liu Blog


OxCaml 的資料競爭自由:以模式系統在編譯期阻斷競爭條件

KC Sivaramakrishnan Blog · 2026-05-07

OxCaml 是 Jane Street 基於 OCaml 5 的擴展方言,透過在型別系統中引入模式(modes)的正交標注,在編譯期靜態保證多 domain 程式不存在資料競爭。作者 KC Sivaramakrishnan 詳細說明其類型系統設計,以及與 OCaml 5 原生 domain 模型的整合方式。

模式系統的兩個維度

OxCaml 新增兩個正交的模式軸:

  • Contention 軸uncontended ⊑ shared ⊑ contended,預設 uncontended):追蹤值是否可能被多個 domain 同時存取。讀取或寫入可變欄位需要 uncontended 狀態;contended 值的可變欄位操作被禁止,因為「另一個 domain 可能正在寫入」。
  • Portability 軸portable ⊑ nonportable,預設 nonportable):決定值是否可安全跨 domain 邊界傳遞。送至其他 domain 的 closure 必須是 portable;其中的捕獲值自動變為 contended

競爭自由的保證機制

資料競爭的四個必要條件(多個 domain、共享狀態、並發寫入、普通 ref)在 OxCaml 的型別系統中無法同時滿足:portable closure 中的可變欄位因 contention 規則而不可存取,編譯器在任何代碼執行前即拒絕有問題的模式

需要共享可變狀態時,Portable.Atomic.t 類型同時具備 portableuncontended 屬性,允許透過原子操作安全地跨 domain 讀寫計數器等共享資料,而無需手動加鎖。

與 OCaml 5 的關係

OCaml 5 原生允許未同步的 closure 共享跨 Domain 邊界,開發者需自行避免競爭;OxCaml 的類型檢查器將這個責任從執行期移至編譯期,在未同步的共享被允許之前就予以拒絕。

原始來源:KC Sivaramakrishnan Blog


End of article
0
Would love your thoughts, please comment.x
()
x