OCaml 多核心 - 2020 年 10 月

歡迎來到 2020 年 10 月的多核心 OCaml 報告,由 @shakthimaan、@kayceesrk 以及當然還有我本人彙編。先前的[每月更新](https://discuss.ocaml.org/tag/multicore-monthly) 也可供您參考。

OCaml 4.12.0-dev: 上游 OCaml 樹已分支為 4.12 版本,OCaml 準備團隊正忙於使用生態系統來穩定它。4.12.0 開發串流在多核心支援方面取得了重大進展,特別是在執行階段處理裸指標方面。此版本將附帶一個裸指標的動態檢查器,您可以使用它來驗證您自己的程式碼庫是否沒有裸指標,因為這將是 OCaml 5.0 和多核心相容性的先決條件。此檢查器可透過 --enable-naked-pointers-checker 配置選項啟用。

與上游和多核心樹的融合: 當我們將我們的樹與上游 OCaml 合併時(現在上游架構變更與多核心的要求同步,這已成為可能),多核心 OCaml 樹已看到顯著的穩健性改進。特別是,多核心現在的全局 C 根處理得更好,因為它使用上游 OCaml 方案,並且 GC 顏色方案也與上游 OCaml 的完全匹配。這表示當使用多核心 OCaml(使用 no-effects-syntax 分支)建置時,來自 opam 的社群函式庫的效果越來越好。

功能: 多核心 OCaml 現在也使用網域本地分配緩衝區來簡化其內部結構。我們現在也正在努力對 IO 子系統進行基準測試,並且已新增對 Lwt 並發函式庫的 CPU 並行性的支援,以及使用多核心 OCaml、Lwt 和 httpaf 更新新的基於非同步效果的 IO(aeio)在 http-effects 函式庫中。

基準測試: Sandmark 基準測試套件具有額外的配置選項,並且該專案中有新的提案,旨在盡可能利用 OCaml 工具和生態系統。

與先前的更新一樣,多核心 OCaml 正在進行和已完成的任務會先列出,然後是 Sandmark 基準測試套件的改進。最後,會提及與上游 OCaml 相關的工作以供您參考。

多核心 OCaml

正在進行

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

    此 PR 是朝向使用網域本地分配緩衝區邁出的一步。使用 Minor_heap_max 大小來保留次要堆積區域,並使用 Is_young 來依賴邊界檢查。可以使用 OCAMLRUNPARAM 環境變數來覆寫 Minor_heap_max

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

    努力取代現有的全域根實作,使其與 OCaml 的 globroots 一致。目標還包括當網域終止時,擁有每個網域的跳過清單和全域孤立項。

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

    主收集器中的 垃圾收集器顏色方案變更現在已回溯移植到多核心 OCaml。mark_entry 不包含 endmark_stack_push 更接近主幹,並且 caml_shrink_mark_stack 已從主幹改編。

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

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

已完成

Systhreads 支援

  • ocaml-multicore/ocaml-multicore#381 使用 pthreads(網域執行內容)重新實作 Systhreads

    使用 pthreads 重新實作 Systhreads 的工作已針對多核心 OCaml 完成。已引入網域執行內容 (DEC),允許在網域之上執行多個執行緒。

  • ocaml-multicore/ocaml-multicore#410 systhreads: caml_c_thread_registercaml_c_thread_unregister

    caml_c_thread_registercaml_c_thread_unregister 函式已重新匯入 systhreads。在多核心 OCaml 中,C 程式碼建立的執行緒將註冊到網域 0 執行緒鏈。

網域本地儲存

  • ocaml-multicore/ocaml-multicore#404 Domain.DLS.new_key 接受初始化程式

    如果尚未初始化,Domain.DLS.new_key 現在接受初始化程式引數,以將關聯值指派給索引鍵。此外,Domain.DLS.get 不再傳回選項值。

  • ocaml-multicore/ocaml-multicore#405 重做 Domain.DLS.get 搜尋函式,使其不再配置記憶體

    已更新 Domain.DLS.get 以移除任何記憶體配置,如果索引鍵已存在於網域本地儲存中。此 PR 也會變更 search 函式以接受所有輸入作為變數,而不是來自環境的封閉程式。

Lwt

雜項

  • ocaml-multicore/ocaml-multicore#406 移除 RPC 的 ephemeron 使用

    使用 stop-the-world 次要 GC 時不需要網域間機制,因此已在 ephemeron 實作中移除。此 PR 也會清理並簡化 ephemeron 資料結構和程式碼。

  • ocaml-multicore/ocaml-multicore#411 修正 internal_variable_names 中 presume 和 presume_arg 的錯字

    一個小的錯字錯誤修正,將 internal_variables_names.ml 中的 PresumePresume_arg 重新命名。

  • ocaml-multicore/ocaml-multicore#414 修正 Ppoll semantics_of_primitives 項目

    已修正 Ppollsemantics_of_primitives 項目,該項目導致 flambda 建置移除輪詢點。

  • ocaml-multicore/ocaml-multicore#416 修正回呼效果錯誤

    此 PR 修正在 C 到 OCaml 回呼時,阻止效果跨越 C 回呼邊界的錯誤。堆疊父項會在回呼之前清除,並在之後還原。它也會使堆疊父項成為本機根,以便 GC 可以在回呼內部看到它。

基準測試

正在進行

組態

  • ocaml-bench/ocaml-bench-scripts#12 新增對平行多重基準測試目標和 JSON 輸入的支援

    現在在執行平行基準測試時,會新增並傳遞 RUN_CONFIG_JSONBUILD_BENCH_TARGET 變數。指定了預設值,以便序列基準測試仍可執行,而不需要明確要求相同的值。

  • ocaml-bench/sandmark#180 筆記本重構和使用者變更

    目前正在進行重構工作,以使平行基準測試具有互動性。The Littlest JupyterHub 安裝上的使用者帳戶可直接存取系統上從 ocaml-bench-scripts 產生的基準測試結果。

  • ocaml-bench/sandmark#189 新增對 JSON 組態檔中包裝函式的環境支援

    OCAMLRUNPARAM 現在在執行階段以環境變數的形式傳遞給基準測試,以便可以使用不同的參數值來取得多個結果以進行比較。用例和討論可在 使用不同的 OCAMLRUNPARAM 執行基準測試問題中找到。環境變數可以在 run_config.json 檔案中指定,如下所示

     {
        "name": "orun_2M",
        "environment": "OCAMLRUNPARAM='s=2M'",
        "command": "orun -o %{output} -- taskset --cpu-list 5 %{command}"
      }
    

提案

  • ocaml-bench/sandmark#159 實作更好的方式來描述任務集 cpulist

    仍在進行討論,以實作更好的方式來取得基準測試執行的核心任務集清單。這是為了能夠指定超執行緒核心、NUMA 區域以及要用於平行基準測試的特定核心。

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

    已提供根據執行時間對基準測試進行分類的提案。已建議下列分類類型

    • lt_1s:執行時間少於 1 秒的基準測試。
    • lt_10s:執行時間至少 1 秒,但少於 10 秒的基準測試。
    • 10s_100s:執行時間至少 10 秒,但少於 100 秒的基準測試。
    • gt_100s:執行時間至少 100 秒的基準測試。

    相關的 PR 可在 基準測試分類中找到。

  • 我們正在探索使用 opam-compiler 切換環境來建置 Sandmark 效能測試套件。合併 systhreads 相容性支援 後,現在我們可以在切換環境內原生安裝 dune 以及其他基準測試程式。透過這種方法,我們希望能將效能測試套件模組化,並逐步完全採用 OCaml 工具和生態系統。

雜項

  • ocaml-bench/sandmark#181 無鎖定地圖基準測試

    這是一個無鎖定的並行雜湊陣列映射樹實作,基於 Prokopec, A. 等人 (2011) 的研究。這個快取感知實作的基準測試目前正在審查中。

  • ocaml-bench/sandmark#183 將數值分析基準測試命名為 crout_decomposition

    Sandmark 儲存庫中存在幾個 LU 分解基準測試,而此 PR 將 numerical-analysis/lu_decomposition.ml 基準測試重新命名為 crout_decomposition.ml。這是為了處理 在數值分析中重新命名 lu_decomposition 基準測試 中兩個基準測試之間可能存在的命名混淆,因為它們的實作方式不同。

已完成

  • ocaml-bench/sandmark#177 在正規化圖表中顯示原始基準數字

    現在,循序筆記本輸出的正規化圖表中包含原始基準數字。例如,maxrsskb 的圖表如下所示

PR 177 Image |690x258

  • ocaml-bench/sandmark#178 變更為使用帶有初始設定式的新 Domain.DLS API

    現在,multicore-minilightmulticore-numerical 基準測試已更新為使用帶有初始設定式的新 Domain.DLS API。

  • ocaml-bench/sandmark#185 清理現有的 effect 基準測試

    此 PR 確保程式碼編譯時沒有任何警告,並新增了 multicore_effects_run_config.json 設定檔和 run_all_effect.sh 腳本來執行相同的操作。

  • ocaml-bench/sandmark#186 非常簡單的 effect 微基準測試以涵蓋程式碼路徑

    現在,已在 Sandmark 測試套件中新增一組四個微基準測試,以測試我們的 effect 系統的吞吐量。其中包括 effect_throughput_cloneeffect_throughput_valeffect_throughput_performeffect_throughput_perform_drop

  • ocaml-bench/sandmark#187 針對 effects 實作 'recursion' 基準測試

    現在,Sandmark 中包含一組遞迴基準測試,用於測量 effect 的額外負荷。其靈感來自 (Manticore 基準測試)[https://github.com/ManticoreProject/benchmark/]。

OCaml

進行中

  • ocaml/ocaml#9876 不要將 young_limit 快取在處理器暫存器中

    此 PR 移除了 ARM64、PowerPC 和 RISC-V 連接埠中將 young_limit 快取在暫存器的操作。目前正在各自的硬體上測試 Sandmark 基準測試。

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

    執行 Sandmark 基準測試是為了分析幾個可最佳化 sweep_slice 的修補程式,以及預取的使用。目標是減少 GC 期間的快取未命中次數。

已完成

  • ocaml/ocaml#9947 新增裸指標動態檢查器

    現在,會在執行時間檢查「裸指標」(危險的堆外指標),並且此 PR 中新增了針對三種模式的測試:裸指標、裸指標與動態檢查器,以及無裸指標。

  • ocaml/ocaml#9951 確保標記堆疊推送最佳化可以處理裸指標

    此 PR 新增了是否將物件推入標記堆疊的精確檢查,以處理裸指標。

我們要感謝社群中所有 OCaml 使用者和開發人員持續不斷的支持、審查和對專案的貢獻。

縮寫

  • AEIO:非同步基於 Effect 的 IO
  • API:應用程式介面
  • ARM:進階精簡指令集機器
  • CPU:中央處理單元
  • DEC:網域執行內容
  • DLS:網域本機儲存
  • GC:垃圾回收器
  • HTTP:超文本傳輸協定
  • JSON:JavaScript 物件表示法
  • NUMA:非一致性記憶體存取
  • OPAM:OCaml 套件管理員
  • OS:作業系統
  • PR:提取請求
  • RISC-V:精簡指令集計算 - V
  • RPC:遠端程序呼叫
  • STW:停止世界