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
不包含end
,mark_stack_push
更接近主幹,並且caml_shrink_mark_stack
已從主幹改編。 -
ocaml-multicore/ocaml-multicore#429 修正 STW 中斷競爭
在此 PR 中修正了
caml_try_run_on_all_domains_with_spin_work
中的 STW 中斷競爭,其中在我們中斷其他網域後,初始化了stw_request
的enter_spin_callback
和enter_spin_data
欄位。
已完成
Systhreads 支援
-
ocaml-multicore/ocaml-multicore#381 使用 pthreads(網域執行內容)重新實作 Systhreads
使用 pthreads 重新實作 Systhreads 的工作已針對多核心 OCaml 完成。已引入網域執行內容 (DEC),允許在網域之上執行多個執行緒。
-
ocaml-multicore/ocaml-multicore#410 systhreads:
caml_c_thread_register
和caml_c_thread_unregister
caml_c_thread_register
和caml_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/multicore-opam#33 新增 lwt.5.3.0+multicore
已新增 Lwt.5.3.0 並行函式庫以支援使用多核心 OCaml 的 CPU 並行性。Sudha Parimala 已撰寫一篇部落格文章,介紹其安裝和使用方式。
-
基於非同步效果的 IO 可使用最新的 Lwt 建置,並且 HTTP 效果示範已更新,可使用多核心 OCaml、Lwt 和 httpaf。示範原始程式碼可在 http-effects 儲存庫中找到。
雜項
-
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
中的Presume
和Presume_arg
重新命名。 -
ocaml-multicore/ocaml-multicore#414 修正
Ppoll
semantics_of_primitives
項目已修正
Ppoll
的semantics_of_primitives
項目,該項目導致 flambda 建置移除輪詢點。 -
ocaml-multicore/ocaml-multicore#416 修正回呼效果錯誤
此 PR 修正在 C 到 OCaml 回呼時,阻止效果跨越 C 回呼邊界的錯誤。堆疊父項會在回呼之前清除,並在之後還原。它也會使堆疊父項成為本機根,以便 GC 可以在回呼內部看到它。
基準測試
正在進行
組態
-
ocaml-bench/ocaml-bench-scripts#12 新增對平行多重基準測試目標和 JSON 輸入的支援
現在在執行平行基準測試時,會新增並傳遞
RUN_CONFIG_JSON
和BUILD_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
的圖表如下所示
-
ocaml-bench/sandmark#178 變更為使用帶有初始設定式的新 Domain.DLS API
現在,
multicore-minilight
和multicore-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_clone
、effect_throughput_val
、effect_throughput_perform
和effect_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:停止世界