OCaml 多核心 - 2020 年 11 月

歡迎來到 2020 年 11 月的多核心 OCaml 報告!此更新與先前的更新由 @shakthimaan、@kayceesrk 和 @avsm 彙編。

多核心 OCaml:自從上個月合併了對 systhreads 的支援以來,更多的生態系統套件可以編譯。我們一直在針對 opam 儲存庫進行批量建置(使用專門的 opam-health-check 實例),以找出最後殘留的建置錯誤。大多數的損壞都發生在與垃圾收集器相關的 C stub 套件周圍,儘管我們確實發現了一些實際的多核心錯誤(與使用 dynlink 時的執行緒機制相關)。詳細資訊請見下方的「生態系統」。我們還花費大量時間優化多核心編譯器中的堆疊規範,作為撰寫關於效應系統的草稿論文的一部分(稍後會有更多詳細資訊)。

上游 OCaml:4.12.0alpha2 版本現已發佈,其中包含動態裸指標檢查器,以協助確保您的程式碼僅使用已封裝的外部指標。請在您的程式碼庫上執行它,以協助準備。對於 OCaml 4.13(目前為 trunk)分支,我們舉行了一次完整的 OCaml 開發人員會議,我們在會議中決定了要提交給上游的工作清單。主要的工作是關於 GC 安全點和不快取 次要堆積指標,之後執行時間域支援就具備了所有必要的上游先決條件。這兩個 PR 都對效能高度敏感,因此需要仔細研究圖表(儘管 @stedolan 不可抑制地提供了 大規模的順道優化)。

Sandmark 基準測試:lockfree 和 Graph500 基準測試已分別新增和更新至 Sandmark,我們將繼續努力處理工具方面的問題。基準測試也在 AMD、ARM 和 PowerPC 硬體上進行,以研究編譯器的效能。關於現有 OCaml,安全點 PR 現在已提交審查。

與先前的更新一樣,首先列出多核心 OCaml 任務,然後列出 Sandmark 基準測試套件的進度。最後,提及上游 OCaml 相關工作,以供您參考。

多核心 OCaml

進行中

  • ocaml-multicore/ocaml-multicore#439 Systhread 生命周期工作

    改進了 systhreads 的初始化,用於一般資源處理,並釋放描述符和堆疊。現在在執行時間中,域終止時有一個新的掛勾。

  • ocaml-multicore/ocaml-multicore#440 ocamlfind ocamldep 在無效應語法分支中掛起

    nocrypto 套件無法為多核心 OCaml 無效應語法分支建置,並且 ocamlfind 持續迴圈。已建立一個最小測試範例來重現此問題。

  • ocaml-multicore/ocaml-multicore#443 次要堆積分配啟動成本

    一個問題,用於追蹤對大型次要堆積大小對 OCaml 多核心程式影響的持續調查。問題中提供了各種次要堆積大小的循序和並行執行結果。

  • ocaml-multicore/ocaml-multicore#446 在次要收集結束時收集 GC 統計資料

    目標是在 parallel_minor_gc 結構描述中,藉由使用次要收集期間存在的屏障,來移除在 GC 統計資料收集中使用雙緩衝。如圖所示,基準測試的執行速度與現有 OCaml 相比沒有太多減慢。PR 446 圖表影像

已完成

上游

  • ocaml-multicore/ocaml-multicore#426 取代全域根實作

    此 PR 使用 OCaml 的 globroots 取代現有的全域根實作,其中實作會將鎖定放置在跳過清單周圍。未來,將會移除 Caml_root 的使用,以及其在 globroots 中的使用。

  • ocaml-multicore/ocaml-multicore#427 垃圾收集器色彩變更回溯移植

    來自主線的 垃圾收集器色彩變更 PR 現在已回溯移植至多核心 OCaml。這包括 mark_stack_push 的最佳化,mark_entry 不包含 end,並且 caml_shrink_mark_stack 已從主線調整。

  • ocaml-multicore/ocaml-multicore#432 移除堆疊切換時的 caml_context 推入/彈出

    移除堆疊切換時 caml_context 推入/彈出的動機是使實作更容易理解,並更接近上游 OCaml。

堆疊改進

  • 修正掃描堆疊時的堆疊溢位 #431 修正問題 421:掃描堆疊時的堆疊溢位

    caml_scan_stack 現在使用 while 迴圈,以避免在光纖深度巢狀時發生的堆疊溢位邊緣案例。

  • ocaml-multicore/ocaml-multicore#434 效果堆疊切換的 DWARF 修正

    此 PR 針對使用 DWARF 驗證器發現的問題,提供了 runtime/amd64.S 的修正。此修補程式還清理了已註解的無用程式碼,並在我們在 caml_runstack 中執行 caml_free_stack 時更新 DWARF 資訊。

  • ocaml-multicore/ocaml-multicore#435 標記堆疊溢位回溯移植

    已更新標記堆疊溢位實作,使其更接近主線 OCaml。首先將集區新增至跳過清單以避免重複,然後在主要週期期間標記 pools_to_rescan 中的集區。下方顯示了使用標記堆疊溢位時,finalise 基準測試的時間差異結果

PR 435 Graph Image

  • ocaml-multicore/ocaml-multicore#437 使用 continue 切換堆疊時,避免配置 C 呼叫

    已更新 caml_continuation_use 以使用 caml_continuation_use_noexc,並且不會擲回例外狀況。不再需要配置 C caml_c_call 來呼叫 caml_continuation_use_noexc

  • ocaml-multicore/ocaml-multicore#441 清理並更多註解 amd64.S 中的 caml_runstack

    此 PR 新增了有關如何切換堆疊的註解,並移除了 x86 組譯器中不必要的指令。

  • ocaml-multicore/ocaml-multicore#442 光纖堆疊快取 (v2)

    新增光纖堆疊的堆疊快取,這也修復了測試套件中的錯誤 (DEBUG memset、初始化順序)。在管理堆疊快取時,我們避免了從 struct stack_info 中間接處理,並有效計算給定堆疊大小的快取可用清單桶。

生態系統

  • ocaml-multicore/lockfree#5 移除 Kcas 相依性

    現在 Kcas.Wl 模組已取代為多核心 stdlib 中提供的 Atomic 模組。指數退避是使用 Domain.Sync.cpu_relax 實作的。

  • ocaml-multicore/domainslib#21 指向新的儲存庫 URL

    感謝 Sora Morimoto (@smorimoto) 提供修補程式,將 URL 更新為正確的 ocaml-multicore 儲存庫。

  • ocaml-multicore/multicore-opam#40 新增多核心 Merlin 和 dot-merlin-reader

    一個修補程式,使 merlin 和 dot-merlin-reader 可以與多核心 OCaml 4.10 一起使用。

  • ocaml-multicore/ocaml-multicore#403 嘗試在多核心上建置 Tezos 時發生區段錯誤

    有關取代全域根實作的最新修正,以及修復 STW 中斷與無效應語法分支的競爭,已解決此問題。

編譯器修正

  • ocaml-multicore/ocaml-multicore#438 允許 C++ 使用 caml/camlatomic.h

    包含 extern "C" 標頭,以允許 C++ 使用 caml/camlatomic.h 來建置 ubpf.0.1。

  • ocaml-multicore/ocaml-multicore#447 domain_state.h:使用 -pedantic 時移除警告

    一個修正程式,使用 CAML_STATIC_ASSERT 來檢查 domain_state.h 中 caml_domain_state 的大小,以便在使用 -pedantic 時移除警告。

  • ocaml-multicore/ocaml-multicore#449 修正 C++ 中使用 stdatomic.h 的問題,以確保正常運作

    更新 caml/camlatomic.h,其中包含 extern C++ 宣告,以在 C++ 內使用它。這會建置 upbf.0.1 和 libsvm.0.10.0 套件。

其他

  • ocaml-multicore/ocaml-multicore#422 簡化次要堆積配置邏輯和遮罩

    引入 Minor_heap_max 大小以保留次要堆積區域,並使用 Is_young 來依賴邊界檢查。可以使用 OCAMLRUNPARAM 環境變數覆寫 Minor_heap_max 參數。此實作方法旨在搭配使用 Domain 本機配置緩衝區。

  • ocaml-multicore/ocaml-multicore#429 修正 STW 中斷競爭

    針對 caml_try_run_on_all_domains_with_spin_work 中的 STW 中斷競爭的修正。我們在其他網域中斷後,現在初始化了 stw_requestenter_spin_callbackenter_spin_data 欄位。

  • ocaml-multicore/ocaml-multicore#430 新增測試以練習儲存的繼續執行和 GC

    此 PR 新增測試涵蓋範圍,用於 GC 與儲存的、複製的和捨棄的繼續執行之間的互動,以練習次要和主要收集器。

  • ocaml-multicore/ocaml-multicore#444 將 'parallel_minor_gc' 分支合併至 'no-effect-syntax'

    parallel_minor_gc 分支已合併至 no-effect-syntax 分支,我們將嘗試使 no-effect-syntax 分支保持在最新變更。

基準測試

進行中

  • ocaml-bench/sandmark#196 依標籤篩選基準測試

    增強功能,朝向基於標籤過濾基準測試的通用實作邁進,而不是依賴自訂目標(例如 _macro.json 或 _ci.json)。

  • ocaml-bench/sandmark#191 使 parallel.ipynb 筆記本具有互動性

    parallel.ipynb 筆記本已變得具有互動性,透過下拉式選單來選擇用於分析的 .bench 檔案。筆記本的 README 已與頂層 README 檔案合併。一個範例 4.10.0.orunchrt.bench 以及 *pausetimes_multicore.bench 檔案已移至 test artifacts/ 資料夾,供使用者測試。

  • 我們正持續測試使用 opam-compiler 切換環境來執行 Sandmark 基準測試套件。我們已能夠為 ocaml-multicore:no-effect-syntax 分支建置相依性、orunrungenOCurrent 管線及其相依性,以及 ocaml-ci。我們希望能夠以所需的 OCaml 工具和生態系統,收斂到 2.0 實作。

已完成

  • ocaml-bench/sandmark#179 [RFC] 根據執行時間分類基準測試

    基準測試分類 PR 已解決,現在根據基準測試的執行時間進行分類

    • lt_1s:執行時間少於 1 秒的基準測試。
    • lt_10s:執行時間至少 1 秒,但少於 10 秒的基準測試。
    • 10s_100s:執行時間至少 10 秒,但少於 100 秒的基準測試。
    • gt_100s:執行時間至少 100 秒的基準測試。
  • ocaml-bench/sandmark#189 為 JSON 組態檔中的封裝器新增環境支援

    現在,在執行時,OCAMLRUNPARAM 引數可以環境變數的形式傳遞。環境變數可以在 run_config.json 檔案中指定,如下所示

     {
        "name": "orun_2M",
        "environment": "OCAMLRUNPARAM='s=2M'",
        "command": "orun -o %{output} -- taskset --cpu-list 5 %{command}"
      }
    
  • ocaml-bench/sandmark#183 對於數值分析基準測試,使用 crout_decomposition 名稱

    numerical-analysis/lu_decomposition.ml 基準測試現在已重新命名為 crout_decomposition.ml,以避免命名混淆,因為 Sandmark 中有幾個 LU 分解基準測試。

  • ocaml-bench/sandmark#190 將 trunk 升級至 4.13.0

    Sandmark ocaml-versions/ 中的 trunk 版本現在已更新為使用 4.13.0+trunk.json

  • ocaml-bench/sandmark#192 更正 GraphSEQ

    已為 Graph500 基準測試提供 Kronecker 產生器的微小修正。

  • ocaml-bench/sandmark#194 Lockfree 基準測試

    Sandmark 現在已包含序列和並行實作的 lockfree 基準測試,並且使用 lockfree_bench 標籤。時間和加速的說明如下

PR 194 Time Image PR 194 Speedup Image

OCaml

進行中

  • ocaml/ocaml#9876 請勿在處理器暫存器中快取 young_limit

    正在使用 Sandmark 基準測試執行來評估在暫存器中移除 young_limit 快取的影響,以測試對 ARM64、PowerPC 和 RISC-V 連接埠硬體的影響變更。

  • ocaml/ocaml#9934 掃描的預先擷取最佳化

    PR 包含對 sweep_slice 的最佳化,以使用預先擷取並減少 GC 期間的快取未命中。標準化的執行時間圖如下所示

PR 9934 Graph

  • ocaml/ocaml#10039 安全點

    針對 4.11 分支的 AMD64 安全點實作草稿,透過將新的 Ipoll 操作新增至 Mach 來實作。下面給出在 AMD Zen2 機器上的基準測試結果

PR 10039 Benchmark

非常感謝所有 OCaml 使用者和開發人員持續的支持,以及對專案的貢獻。

縮寫

  • ARM:進階 RISC 機器
  • DWARF:使用屬性記錄格式進行除錯
  • GC:垃圾收集器
  • JSON:JavaScript 物件表示法
  • OPAM:OCaml 套件管理器
  • PR:提取請求
  • PR:提取請求
  • RFC:徵求意見
  • RISC-V:精簡指令集計算 - V
  • STW:停止世界
  • URL:統一資源定位器