OCaml 多核心 - 2021 年 11 月

歡迎來到 2021 年 11 月的 多核心 OCaml 月報!本月的更新以及先前的更新是由我 @ctk21、@kayceesrk 和 @shakthimaan 共同編寫。

核心團隊程式碼審查

11 月下旬,整個 OCaml 開發團隊召開為期一週的程式碼審查和決策會議,討論將多核心合併到 OCaml 5.0。由於補丁集的大小,我們將設計和簡報分成五個工作組。以下是每次對話的摘要。一如既往,這些決策可能會因核心團隊發現問題而有所變更,因此請不要根據這些決策為您的下游專案做出任何關鍵決策。我們公開這些資訊的目的是為了聽取您可能認為我們需要根據您自己的程式碼庫中的其他資料進行更正的意見。

為了簡潔起見,我們不包含開發人員會議的完整會議記錄。總體而言,多核心修補程式被認為在廣泛上是穩健且合適的,我們記錄了重要的決策和任務

  • Pre-MVP:在未來一個月內向 ocaml/ocaml 發送 PR 之前需要完成的任務。
  • Post-MVP for 5.00:在 5.00 發佈之前需要在 ocaml/ocaml 上完成的任務。這些任務將會阻礙 OCaml 5.00 的發佈。
  • Post-5.00:在 2022 年初/中期發佈 5.00 之後的未來任務。

WG1:垃圾收集器

多核心執行階段會變更記憶體配置和垃圾收集器,以支援 OCaml 執行的多個並行執行緒。它利用了停止世界式的並行小型收集器、類似 StreamFlow 的多執行緒配置器以及幾乎並行的主要收集器。

WG1 決定壓縮將不會包含在 5.0 的初始版本中,因為我們最適合的配置器顯示良好的記憶體配置策略可以消除昂貴壓縮的需求。當然,多核心記憶體配置器與最佳擬合不同,因此我們需要社群的投入,以確保我們關於不需要壓縮的假設是穩健的。如果您確實看到您的應用程式堆積在 5.0 進入測試版時變得非常零碎,請與我們聯繫。

Pre-MVP

  • 移除任何無裸指標檢查器的痕跡,因為它在無頁表的多核心執行階段中無關。
  • 為測試套件執行 make parallel 應該可以運作
  • assert 移動到 CAMLassert
  • 如何從 C 進行安全點:新增關於 caml_process_pending_actions 的文件,以及一個用於多核心的長時間執行 C 綁定的測試套件案例
  • 採用 ephemeron bucket 介面,並執行與 4.x OCaml trunk 相同的操作
  • 檢查並記錄 NOT_MARKABLE 可以用於像 ancient 這樣想要堆積物件的函式庫
  • 檢查我們記錄了我們返回的 GC 統計資料類型(全域與網域本機)用於各種統計資料

Post-MVP for 5.00

  • 標記堆疊溢位修復,這不應該影響大多數執行階段配置設定檔

Post-5.00

  • Statmemprof 實作
  • 標記預先提取
  • 研究替代的小型堆積實作,以維持效能但減少虛擬記憶體使用量

WG2:網域

多核心中的每個網域都可以與其他網域並行執行 OCaml 的執行緒。在 OCaml 中新增了數項功能,以產生新的網域、加入正在終止的網域並提供網域本機儲存。有一個 stdlib 模組 Domain 和底層的執行階段網域結構。最近幾個月的重大簡化是可以使用標準 Mutex/Channel/Semaphore 模組,而不是先前在 Domain 中可用的較低層級的同步基本元素。

執行階段結構的挑戰是在網域終止和產生的情況下,準確地維護必須參與停止世界部分的網域集合,並確保網域在主要 mutator 處於封鎖呼叫中時為停止世界請求提供服務;這使用從 caml_enter_blocking_section / caml_leave_blocking_section 發出訊號的備份執行緒來處理。

討論了多核心 OCaml 記憶體模型,並為 arm64 選擇了正確的方案(來自 論文的表 5b)。當地資料競爭自由 (LDRF) 屬性被認為是 OCaml 5.0 記憶體模型的一種平衡且可預測的方法。我們可能需要依賴 OCaml 5.0 中用於放鬆原子操作的 >C11 編譯器,因此這表示 MVP 將放棄 Windows MSVC 支援(但 mingw 將會運作)。

Pre-MVP

  • 使網域 ID 抽象化,並提供 string_of_id
  • 記錄使用 Field 巨集進行初始化寫入對於記憶體模型來說是正常的。同時強調所有寫入都需要使用 caml_modify(即使是立即數)
  • 檢查 selectgen「共同效應」對於 DLS.get 是否正確
  • domain.c 需要更多註解以協助讀者
    • 關於備份執行緒狀態機器以及事情發生的位置
    • 網域產生/加入
  • 註解/檢查為什麼在被產生者和產生者中呼叫 install_backup_thread
  • 檢查為什麼網域終止正在使用互斥鎖進行加入(而不是互斥鎖、條件變數對)

Post-5.00

  • 為使用者提供一種機制來檢索可用的處理器數量。這也可以由函式庫實作。
  • 新增原子可變記錄欄位
  • 新增原子變數陣列

WG3:執行階段多網域安全性

多核心 OCaml 以回溯相容的方式支援系統執行緒。執行模型保持不變,除了轉換為網域而不是單一執行內容。

每個網域都會取得自己的執行緒鏈結:這表示雖然在單一網域上一次只能執行一個系統執行緒(類似於 trunk),但許多網域仍然可以並行執行,其系統執行緒鏈結是獨立的。為了實現此目的,採用了一個執行緒表,以便每個網域都可以維護自己的獨立鏈結。內容切換現在需要格外小心以處理備份執行緒。當執行緒目前處於封鎖區段時,備份執行緒會負責 GC 職責。系統執行緒需要小心何時發出訊號。

用於定期強制執行緒搶佔的刻度執行緒已更新為不依賴訊號(因為多核心訊號模型不允許有效率地完成此操作)。相反地,我們依賴多核心執行階段的中斷基礎架構,並觸發一個「外部」中斷,該中斷將回呼到系統執行緒以強制產生 yield。

現有的 Dynlink API 是幾十年前為使用 OCaml 編寫的網頁瀏覽器(稱為「mmm」)而設計的,並且是有狀態的。我們將允許在 OCaml 5.0 MVP 中並行呼叫它,但 WG3 決定開始重新設計 Dynlink API 以減少狀態性。

程式碼片段現在儲存在無鎖定跳過清單中,以允許多個執行緒以執行緒安全的方式同時處理 codefrags 結構。清理(即釋放未使用的程式碼片段項目)需要格外小心:這應該只發生在一個網域上,並且這是在主要週期的末尾完成的。對於有興趣的人,建議閱讀 ocaml-multicore#672,以查看現在使用的並行跳過清單結構。

多核心中的訊號具有以下行為,WG3 決定變更其行為,以允許從 mutator 的角度合併多個訊號

  • 具有單一網域的程式應該具有與 trunk 大致相同的訊號行為。這包括將訊號傳遞到該網域上的系統執行緒。
  • 具有多個網域的程式以全域方式處理訊號。除了透過執行緒 sigmask 控制之外,無法將訊號導向個別網域或執行緒。記錄訊號的網域可能不是正在執行 OCaml 訊號處理常式的網域。

現在,框架描述元修改鎖定在互斥鎖後面,以避免如果不同的執行緒嘗試同時將變更套用到框架表時發生競爭。釋放舊的框架表是在主要週期的末尾(這是 STW 區段)完成的,以確保沒有執行緒將再使用此舊的框架表。

多核心 OCaml 包含一個適用於多個網域的 eventlog 版本。它透過為每個網域設定一個單獨的 CTF 檔案來實現此目的,但這是一個臨時解決方案。我們希望用基於每個網域環形緩衝區的現有原型取代此實作,該原型可以從 OCaml 和 C 以程式設計方式使用。這將是 eventlog 的一般化,因此如果它尚未被廣泛採用,我們應該能夠移除現有的介面。

Pre-MVP

  • 重寫 intern.c,使其不執行 GC。此程式碼對效能敏感,因為編譯器會透過取消編列它們來讀取 cmi 檔案。
    • 針對 big.ml(來自 @stedolan)和二元樹基準(來自 @xavierleroy)進行基準測試。
  • 確保系統執行緒中的 m->waiters 原子操作正確且安全。
  • 寫下 Thread.exit 的選項,以便在合併期間或之後進行討論,以及如果只有一個網域結束而其他網域繼續執行時該怎麼辦。不應該是阻礙問題。從原始 trunk 變更語意是可以的。
  • ocaml-multicore/ocaml-multicore#740 開始,m->busy 不再是原子操作,應該進行檢閱和合併。
  • Dynlink 限制為網域 0,因為它是一個可變介面且難以同時使用。
  • 訊號堆疊應該從計數移動到合併語意。
  • 嘗試延遲網域產生時的訊號處理,以便 Caml_state 有效。
  • 如果可能,移除 total_signals_pending

Post-MVP for 5.00

  • 探查 opam 的 eventlog 使用情況(在 OCaml 4.13 中引入),以判斷移除它是否會破壞任何應用程式。
  • Eventring 合併正常,如果功能保持等效,則可以變更 eventlog API。
  • (也可能是 post 5.00)系統執行緒的 TLS。

Post-5.00

  • 取得更多關於 Dynlink 使用情況的資料,並設計一個不太具狀態性的新 API。
  • @xavierleroy 建議根據新的配置器重新設計封送處理。

WG4:Stdlib 變更

將 Stdlib 移植到 OCaml 5.00 的主要指導原則是

  1. OCaml 5.00 預設不為可變資料結構和介面提供執行緒安全性。
  2. 即使在多個網域並行使用 stdlib 時,OCaml 5.00 也能確保記憶體安全(不會當機)。
  3. 觀察上純粹的介面在 OCaml 5.00 中仍然如此。

對於具有特定可變介面(例如 Queue、Hashtbl、Stack 等)的 OCaml 函式庫,為了避免影響循序效能,它們將不會被設為網域安全。使用平行處理的程式需要在並行存取這些模組時,自行加入鎖定機制來確保安全。具有頂層可變狀態的模組(例如 Filename、Random、Format 等)將會被設為網域安全。其中一些模組,例如 Random,正在進行大規模的重新設計,以使用新的方法,如可分割的 PRNG。這些選擇的動機以及更深入的討論可以在 Multicore OCaml wiki 頁面中找到。

WG4 也注意到,我們會接受可並行安全的標準函式庫可變模組的替代版本(例如具有 Concurrent.Hashtbl),並且也希望看到 OCaml 社群獨立開發更多無鎖定的函式庫。總體而言,WG4 認可社群參與將 OCaml 函式庫移植到平行安全的重要性。我們的目標是在語言中加入 ocamldoc 標籤,以標記模組/函式的安全性,並希望在 OCaml 5.0 之前將其納入新的統一套件資料庫 v3.ocaml.org

Lazy

OCaml 中的 Lazy 值允許透過強制執行來執行延遲計算。一旦 Lazy 計算執行完成,Lazy 值就會更新,以便進一步強制執行可以從先前的強制執行中獲取結果。次要 GC 也會短路強制執行的 Lazy 值,避免跳過 Lazy 物件。Lazy 的實作使用了 Obj 模組中的不安全操作

Lazy 的實作在 OCaml 5.00 中已設為執行緒安全。對於單執行緒的使用,Lazy 模組保留了向後相容性。對於多執行緒的使用,Lazy 模組加入了同步機制,以便在多個網域同時強制執行未強制執行的 Lazy 值時,其中一個網域將會執行延遲計算,而其他網域將會收到新的例外狀況 RacyLazy

Random

透過 ocaml-multicore#582,我們擁有網域本地 PRNG,其運作方式與標準 OCaml 非常相似。特別是,對於循序 OCaml 程式,行為保持不變。但對於平行程式來說,情況並不理想。如果沒有明確的初始化,所有網域都會提取相同的初始序列。

ocaml/RFCs#28 中正在討論可分割的 PRNG,並且在 ocaml/ocaml#10701 中使用 Xoshiro256++ PRNG 重新實作 Random。

Format

Format 模組有一些隱藏的全域狀態,用於實作美觀列印框。雖然該模組具有明確的 API 來將格式化程式狀態傳遞給函數,但針對 stdoutstderr 和標準緩衝區,有一些預先定義的格式化程式,它們的狀態由該模組維護。

Format 模組已設為預先定義格式化程式的執行緒安全。我們為每個網域使用格式化程式狀態的網域本地版本,當第一個網域產生時,會延遲切換到此版本。這保留了單執行緒程式碼的效能,同時也適用於多執行緒的使用案例。請參閱 ocaml/ocaml#10453 中的討論摘要。

Mutex、Condition、Semaphore

Mutex、Condition 和 Semaphore 模組與標準 OCaml 中的 systhreads 相同。它們現在位於 stdlib 中。當連結 systhreads 時,相同的模組會用於 systhreads 之間的同步。

Pre-MVP

  • 將 Lazy 標記為非執行緒安全。
    • 統一 RacyLazy 和 Undefined
    • 移除網域本地唯一權杖
    • 移除 try_force
  • 新增 Bucket 模組,用於具有預設循序實作的星體,如 OCaml 4.13 中所示。

Post-MVP for 5.00

  • 為不同的並行安全性引入 ocamldoc 標籤
    • 網域安全
    • systhread 安全
    • 纖程安全
    • 非並行安全 (= !網域安全 || !systhread 安全 || !纖程安全) -- 也用作未經分析並行性的函式庫和函數的佔位符。
  • 在手冊中新增記憶體模型的說明文件。具體來說,沒有憑空出現的值 – 除了指向論文外,無需精確記錄記憶體模型。
  • 對於 Arg 模組,建議棄用目前但不包含整個模組
  • 移除 ThreadUnix 作為一個不再需要 Unix 的簡單模組。
  • Dynlink 應該在其內部具有互斥鎖,以確保它不會當機,尤其是在位元組碼中。

Post-5.00

  • 原子陣列
  • 以 Bucket 模組重新實作星體。
  • 透過使用位元組大小的寫入和 CAS,使 Lazy 標籤的更新與標記分開。

WG5: 纖程

纖程是支援效應處理器的執行階段系統機制。OCaml 中效應處理器的設計已寫在 PLDI 2021 論文中。新增效應處理器的動機以及更多範例可以在 這些投影片中找到。

使用效應處理器程式設計

效應處理器可透過 stdlib/effectHandlers.ml(儘管可能很快會重新命名為 Effect)提供給 OCaml 程式設計師。EffectHandlers 模組公開了兩種效應處理器的變體 – 深層和淺層。深層處理器類似於在計算樹上的折疊,而淺層處理器類似於 案例分割。使用深層處理器,處理器會包裝在續程周圍,而在淺層處理器中則不會。

以下是一個程式範例,該程式使用深層處理器來模擬類似於 Reader 單子的內容。

open EffectHandlers
open EffectHandlers.Deep

type _ eff += Ask : int eff

let main () =
  try_with (fun _ -> perform Ask + perform Ask) ()
  { effc = fun (type a) (e : a eff) ->
      match e with
      | Ask -> Some (fun (k : (a,_) continuation) -> continue k 1)
      | _ -> None }

let _ = assert (main () = 2)

請注意,當我們恢復續程 k 時,計算執行的後續效應也由同一個處理器處理。與此相反,淺層處理器則不會。對於淺層處理器,我們使用 continue_with 而不是 continue。

open EffectHandlers
open EffectHandlers.Shallow

type _ eff += Ask : int eff

let main () =
  let rec loop (k: (int,_) continuation) (state : int) =
    continue_with k state
    { retc = (fun v -> v);
      exnc = (fun e -> raise e);
      effc = fun (type a) (e : a eff) ->
        match e with
        | Ask -> Some (fun (k : (a, _) continuation) -> loop k 1)
        | _ -> None }
  in
  let k = fiber (fun _ -> perform Ask + perform Ask) in
  loop k 1

let _ = assert (main () = 2)

請注意,使用淺層處理器,遞迴是明確的。淺層處理器可以更輕鬆地編碼需要透過執行緒傳遞狀態的案例。例如,以下是編碼計數器的 State 處理器的變體

open EffectHandlers
open EffectHandlers.Shallow

type _ eff += Next : int eff

let main () =
  let rec loop (k: (int,_) continuation) (state : int) =
    continue_with k state
    { retc = (fun v -> v);
      exnc = (fun e -> raise e);
      effc = fun (type a) (e : a eff) ->
        match e with
        | Next -> Some (fun (k : (a, _) continuation) -> loop k (state + 1))
        | _ -> None }
  in
  let k = fiber (fun _ -> perform Next + perform Next) in
  loop k 0

let _ = assert (main () = 3)

雖然這種編碼可以使用深層處理器(透過使用閉包建立計算的常見 State 單子技巧),但使用淺層處理器感覺更自然。一般而言,可以使用淺層處理器輕鬆編碼深層處理器,但反向編碼則具有挑戰性。在目前正在開發的類型化效應工作下,預設將會是淺層處理器,而深層處理器將會使用淺層處理器進行編碼。

稍微回顧一下歷史,目前的實作針對深層處理器進行了調整,並在多次迭代中收集了最佳化。如果淺層處理器在未來幾年變得更加廣泛,則可以進行一些調整,以移除一些配置。也就是說,未來實作中深層和淺層處理器的語意將與目前 OCaml 5.00 分支中的語意保持不變。

Post-MVP for 5.00

  • 新增 ARM64 後端
  • 關於效應處理器用法的說明文件。
  • 目前的堆疊大小應該是纖程堆疊的堆疊大小總和。目前,它只擷取最頂層纖程的大小。
    • 這並不像看起來那麼簡單。恢復續程會附加堆疊。我們應該在那裡進行堆疊溢位檢查嗎?我不應該,因為這會使恢復續程速度變慢。一個想法可能是只在堆疊重新配置時進行堆疊溢位檢查,這會捕捉到常見的情況。

Post-5.00

  • 新增使用框架指標編譯的支援。

十一月活動

這總結了大規模的程式碼審查摘要以及所做的重大決策。總體而言,我們正全力以赴產生 OCaml 5.0 PR,儘管我們在未來幾個月內還有很多工作要做!現在我們繼續就 11 月發生的其他事情進行定期報告。生態系統持續發展,並且 Eio(適用於 OCaml 的基於效應的平行 IO)有了重大更新。

Lwt.5.5.0 已發布,支援將純計算分派到多核心網域。Sandmark 基準測試現在已更新為可針對 5.00 進行建置,並且正在改進 current-bench 工具,以更好地追蹤效能分析和上游合併變更。

與往常一樣,Multicore OCaml 更新會首先列出,其中包含上游工作、說明文件變更和 PR 修復。接著是 EioTezos 的生態系統更新。Sandmark、sandmark-nightly 和 current-bench 工作最後會列出,以供您參考。

Multicore OCaml

進行中

上游

  • ocaml-multicore/ocaml-multicore#669 為網域設定執行緒名稱

    一個為 Multicore OCaml 實作執行緒命名的修補程式。它提供了一個介面,可分別命名網域和執行緒。這些變更現在已使用檢查類型修復程式重新基底。

  • ocaml-multicore/ocaml-multicore#733 改善 Linux 上的虛擬記憶體消耗

    正在進行設計討論,內容涉及協調網域的次要堆積配置以提高虛擬記憶體效能、網域產生和終止、Is_young 執行階段使用的效能和安全性,以及使用 Gc 設定來變更次要堆積大小。

  • ocaml-multicore/ocaml-multicore#735minor_gc.c 中新增 caml_young_alloc_startcaml_young_alloc_end

    caml_young_alloc_startcaml_young_alloc_end 在 Multicore OCaml 中不存在,它們應該與 young_startyoung_end 相同。

  • ocaml-multicore/ocaml-multicore#736 由於缺少 pthread 連結旗標,解壓縮測試套件在 5.0 中失敗

    在測試解壓縮測試套件時,如果未連結 -lpthread,則會觀察到未定義的對 pthread_sigmask 的參考。

  • ocaml-multicore/ocaml-multicore#737 將新的星體 API 移植到 5.00

    不可變星體的 API 已在主幹中合併,並且需要將相應的變更移植到 5.00。

  • ocaml-multicore/ocaml-multicore#740 Systhread 生命週期

    PR 解決了 Multicore 中的 systhreads 生命週期,並在 caml_thread_domain_stop_hookThread.exitcaml_c_thread_unregister 中提供了修復。

  • ocaml-multicore/ocaml-multicore#742 來自非同步審查的次要任務

    來自 OCaml 5.00 版本非同步審查的次要任務列表。主要任務將有其自己的 GitHub 問題。

  • ocaml-multicore/ocaml-multicore#745 Systhreads WG3 評論

    提交名稱應該是自我描述的,優先使用非原子變數,並且當無法配置執行緒描述符時,我們應該引發 OOM。

  • ocaml-multicore/ocaml-multicore#748 WG3 移動 gen_sizeclasses

    PR 將 runtime/gen_sizeclasses.ml 移動到 tools/gen_sizeclasses.ml 並修復檢查類型問題。

  • ocaml-multicore/ocaml-multicore#750 討論 Multicore 下 Lazy 的設計

    正在進行關於 Multicore OCaml 中 Lazy 設計的討論,內容涉及循序 Lazy、並行問題、重複計算和記憶體安全。

  • ocaml-multicore/ocaml-multicore#753 C API 將網域釘選到 C 執行緒?

    一個關於如何設計 API 的問題,該 API 允許從 C 建立「釘選」到現有 C 執行緒的網域。

  • ocaml-multicore/ocaml-multicore#754 改善 emit.mlp 組織

    preproc_fun 函數應移至與目標無關的模組,並且所有序言程式碼都需要在一個地方發出。

  • ocaml-multicore/ocaml-multicore#756 RFC:通用化 Domain.DLS 介面以分割子網域的 PRNG 狀態

    此 PR 示範了「正確」的 PRNG+域語義的實作,其中生成一個域會「分割」PRNG 的狀態。

  • ocaml-multicore/ocaml-multicore#757 審計 stdlib 的可變狀態

    一個追蹤 stdlib 可變狀態審計進度的議題追蹤器。OCaml 5.00 的 stdlib 必須保證記憶體和執行緒安全。

文件

  • ocaml-multicore/ocaml-multicore#741 確保版權標頭格式正確

    原始碼檔案中的版權標頭必須使用新的格式整齊地格式化。如果已存在舊格式,則必須如下所示添加作者、機構詳細資訊

    /**************************************************************************/
    /*                                                                        */
    /*                                 OCaml                                  */
    /*                                                                        */
    /*          Xavier Leroy and Damien Doligez, INRIA Rocquencourt           */
    /*          <author's name>, <author's institution>                       */
    /*                                                                        */
    /*   Copyright 1996 Institut National de Recherche en Informatique et     */
    /*     en Automatique.                                                    */
    /*   Copyright <first year written>, <author OR author's institution>     */
    /*   Included in OCaml under the terms of a Contributor License Agreement */
    /*   granted to Institut National de Recherche en Informatique et en      */
    /*   Automatique.                                                         */
    /*                                                                        */
    /*   All rights reserved.  This file is distributed under the terms of    */
    /*   the GNU Lesser General Public License version 2.1, with the          */
    /*   special exception on linking described in the file LICENSE.          */
    /*                                                                        */
    /**************************************************************************/
    
  • ocaml-multicore/ocaml-multicore#743 未處理的例外應產生更好的錯誤訊息

    請求在編譯器輸出中輸出資訊豐富的 Unhandled_effect <EFFECT_NAME> 錯誤訊息,而不是 Unhandled

  • ocaml-multicore/ocaml-multicore#752 記錄目前 Multicore 測試套件的情況

    關於如何執行 Multicore OCaml 測試套件的文件更新。步驟如下

    $ make world.opt
    $ cd testsuite
    $ make all-enabled
    
  • ocaml-multicore/ocaml-multicore#759 重新命名型別變數以提高清晰度

    stdlib/fiber.ml 中的型別變數已更新以確保一致性和清晰度。

雜項

  • ocaml-multicore/ocaml-multicore#725 已封鎖信號無限迴圈修復

    引入單調的 recorded_signals_counter 以修復當沒有域可以處理被封鎖的信號時,caml_enter_blocking_section 中可能發生的迴圈。還添加了 signals_block.ml 回呼測試。

  • ocaml-multicore/ocaml-multicore#730 ocamlopt 編譯 aws-ec2.1.2color-brewery.0.2 時引發堆疊溢位

    使用 4.14.0+domains+dev0 編譯 aws-ec2.1.2 時引發「堆疊溢位」例外。

  • ocaml-multicore/ocaml-multicore#734 在新域初始化 domain_state 之前發出信號時可能發生段錯誤

    Domain.spawn 建立的域在其到達主要進入點並初始化執行緒局部資料之前收到信號時,可能會導致潛在的區段錯誤。

  • ocaml-multicore/ocaml-multicore#738 當外部函數和 GC 同時執行時,斷言違規

    當 Z3 嘗試釋放在 get_unsat_core 函數中 GC 清理過的物件時,會擲回 Assertion Violation 錯誤訊息。

  • ocaml-multicore/ocaml-multicore#749 Forward_tag 短路機制上的潛在錯誤?

    Obj.forcing_tag 型別的值上短路 Forward_tag 時的錯誤。在次要 GC 中,Forward_tagLazy_tagDouble_tag 型別的值上停用短路。

已完成

上游

  • ocaml-multicore/ocaml-multicore#637 caml_page_table_lookup 在 ocaml-multicore 中不可用

    Multicore 沒有頁表,如果 ancient 參考 caml_page_table_lookup,則不會建置。 移除頁表功能殘留 PR 修復了此問題。

  • ocaml-multicore/ocaml-multicore#727 更新版本號碼

    ocaml-variants.opam 檔案已更新為使用 ocaml-variants.4.14.0+domains

  • ocaml-multicore/ocaml-multicore#728 更新 5.00 分支的 base-domains 套件

    base-domains 套件現在包含 4.14.0+domains。否則,本機 opam 變換上的釘選會在依賴解析時失敗。

  • ocaml-multicore/ocaml-multicore#729 引入 caml_process_pending_signals,如果發生例外則會引發

    此程式碼與主幹中的 caml_process_pending_actions / caml_process_pending_actions_exn 相符,並清除 caml_raise_if_exception(caml_process_pending_signals_exn()) 呼叫。

文件

雜項

  • ocaml-multicore/ocaml-multicore#720 改善與測試套件的短暫物件相容性

    此 PR 修復了 weaktest.ml,並導入上游變更,使短暫物件能夠與中綴物件搭配使用。

  • ocaml-multicore/ocaml-multicore#731 AFL:段錯誤和鎖定重設(修復 #497

    修復程式以使 AFL 指令在 Multicore OCaml 上再次正常運作。此 PR 還將 caml_init_domains 變更為一致地使用 caml_fatal_error

生態系統

正在進行中

  • ocaml-multicore/tezos#8 ci.Dockerfile 擲回警告

    已從 Tezos 中移除強制執行 c99numerics 程式庫,因此不應發生此警告。

  • ocaml-multicore/domainslib#55 setup_pool:選擇排除目前/第一個域?

    不將主執行緒納入集區中的使用案例是有效的請求。使用 async_push 可以協助處理相同情況

    (* main thread *)
    let pool = setup_pool ~num_additional_domains () in
    let promise = async_push pool initial_task in
    (* the workers are now executing the [initial_task] and
       its children. main thread is free to do its thing. *)
    ....
    (* when it is time to terminate, for cleanup, you may optionally do *)
    let res = await pool promise (* waits for the promise to resolve, if not already *)
    teardown_pool pool
    
  • ocaml-multicore/eio#91 [討論] 物件功能/API

    關於將開放物件作為每個函數的第一個參數,以及使用完整單字和表達式(而不是 networkfile_systems 等)的開放討論。

已完成

Eio

  • ocaml-multicore/eio#86 更新 README 以提及 libuv 後端

    已更新 README.md 檔案,提及此程式庫提供基於 libuv 的通用後端,該後端可在大多數平台上運作,並且具有針對 Linux 使用 io-uring 的最佳化後端。

  • ocaml-multicore/eio#89uring 標記為供應商會中斷安裝

    使用 pin-depends 用於 uring,以避免使用 OPAM 時發生任何供應商安裝問題。

  • ocaml-multicore/eio#90 隱式取消

    已將 lib_eio/cancel.ml 新增至 Eio,該檔案已從 Switch 中分離出來。等待中的 Promise 會使用取消環境,而且許多操作不再需要交換引數。

  • ocaml-multicore/eio#92 更新 README 中的追蹤圖

    已更新 README 檔案中的追蹤圖,以顯示兩個計數執行緒為兩條水平線,以及白色區域表示每個執行緒何時正在執行。

    eio-pr-92-trace|690x157

  • ocaml-multicore/eio#93 新增 Fibre.first

    Fibre.first 會傳回第一個完成的纖維的結果,並取消另一個纖維。此 PR 也添加了 tests/test_fibre.md 檔案。

  • ocaml-multicore/eio#94 新增 Time.with_timeout

    模組 Time 現在包含 with_timeoutwith_timeout_extn 函式至 lib_eio/eio.ml

  • ocaml-multicore/eio#95 追蹤取消是否來自父環境

    如果要求父環境退出,則會引發 Cancelled 例外,以便向上傳播取消。如果取消是在內部,則會引發原始例外。

  • ocaml-multicore/eio#96 新增 Fibre.allFibre.pairFibre.anyFibre.await_cancel

    已將 allpairanyawait_cancel 函式新增至 libe_eio/eio.ml 中的 Fibre 模組。

  • ocaml-multicore/eio#97 修復 MDX 警告

    已更新 tests/test_fibre.md 檔案以修復 MDX 警告。

  • ocaml-multicore/eio#98 保留明確的取消環境樹狀結構

    現在可以將取消環境的樹狀結構傾印到輸出中,這對於偵錯很有用。

  • ocaml-multicore/eio#99 使 enqueue 成為執行緒安全

    已將執行緒安全的 Promise、串流和信號量新增至 Eio。make bench 目標可以測試相同情況

    dune exec -- ./bench/bench_promise.exe
    Reading a resolved promise: 4.684 ns
    use_domains,   n_iters, ns/iter, promoted/iter
          false,  1000000,   964.73,       26.0096
           true,   100000, 13833.80,       15.7142
    
    dune exec -- ./bench/bench_stream.exe
    use_domains,  n_iters, capacity, ns/iter, promoted/iter
          false, 10000000,        1,  150.95,        0.0090
          false, 10000000,       10,   76.55,        0.0041
          false, 10000000,      100,   52.67,        0.0112
          false, 10000000,     1000,   51.13,        0.0696
           true,  1000000,        1, 4256.24,        1.0048
           true,  1000000,       10,  993.72,        0.2526
           true,  1000000,      100,  280.33,        0.0094
           true,  1000000,     1000,  287.93,        0.0168
    
    dune exec -- ./bench/bench_semaphore.exe
    use_domains,  n_iters, ns/iter, promoted/iter
          false, 10000000,   43.36,        0.0001
           true, 10000000,  303.89,        0.0000
    
  • ocaml-multicore/eio#100 在更多地方傳播回溯

    已更新 libe_eio/fibre.mllib_eio_linux/eio_linux.ml 以允許回溯傳播。

Tezos

  • ocaml-multicore/tezos#10 修復 make build-deps,修復 NixOS 支援

    此修補程式修復了 make build-deps/build-dev-deps,並且已從 tezos-opam-repository 中移除 conf-perl

  • ocaml-multicore/tezos#15 修復 scripts/version.h

    現在已透過在 scripts/version.h 檔案中正確匯出變數來修復 CI 建置失敗。

  • ocaml-multicore/tezos#16 修復 make build-depsmake build-dev-deps 以安裝正確的 OCaml 變換

    現在已從指令碼檔案中移除硬式編碼的 OCaml 變換,並且使用來自 script/version.h 的變換資訊與 make build-depsmake build-dev-deps 目標。

  • ocaml-multicore/tezos#17 在對 4.12.0+domains 分支的提取請求上啟用 CI

    已針對 4.12.0+domains 分支的提取請求啟用 CI。

  • ocaml-multicore/tezos#20 上游更新

    合併來自 Tezos 儲存庫的最新上游建置、程式碼和文件變更。

雜項

  • ocaml-multicore/tezos-opam-repository#6 更新

    已更新 tezos-opam-repository 中的依賴套件,並已新增 mtime.1.3.0 作為依賴項。

  • ocaml-multicore/ocaml-uring#40BosRresult 移除測試依賴項

    已從專案中移除 BosRresult 依賴項,因為我們已經依賴於提供所需函式的 OCaml >= 4.12。

  • ocaml-multicore/ocaml-uring#42 處理 test_cancel_late 中的競爭

    透過此合併的 PR,已修復 tests/main.mltest_cancel_late 的競爭條件問題。

  • ocaml-multicore/domainslib#51 使用效果處理器

    現在任務是使用效果處理器建立的,並且新增了一個 test_deadlock.ml 測試。

效能基準測試

Sandmark 與 Sandmark-nightly

進行中

  • ocaml-bench/sandmark-nightly#21 新增 5.00 變體

    Multicore OCaml 現在會追蹤 OCaml trunk,而 4.12.0+domains+effects 和 4.12+domains 將只會有錯誤修復。現在 sandmark-nightly 需要包含下列變體

    • OCaml trunk,循序,執行階段 (吞吐量)
    • OCaml 5.00,循序,執行階段
    • OCaml 5.00,平行,執行階段
    • OCaml trunk,循序,暫停時間 (延遲)
    • OCaml 5.00,循序,暫停時間
    • OCaml 5.00,平行,暫停時間
  • ocaml-bench/sandmark#262 ocaml-migrate-parsetree.2.2.0+stock 無法使用 ocaml.5.00.0+trunk 編譯

    ocaml-migrate-parsetree 相依性不適用於 OCaml 5.00,我們需要等待 5.00 AST 凍結,才能使用 Sandmark 建置此套件。

  • 一個 package_remove 功能正在新增至 Sandmark 的 -main 分支,允許動態移除已知在最近的開發分支上無法建置的任何相依性套件。

已完成

  • ocaml-bench/sandmark-nightly#22 修復資料框交集順序問題

    dataframe_intersection 函式已更新,可正確篩選出要比較的變體中不存在的效能基準。

  • ocaml-bench/sandmark#248 Coq 無法建置

    現在使用新的 Coq tarball coq-multicore-2021-09-24,搭配 Sandmark 為各種 OCaml 變體進行建置。

  • ocaml-bench/sandmark#257 將最新的 Coq 2019-09 新增至 Sandmark

    Sandmark 中的 Coq 效能基準現在可為 4.14.0+domains 和 OCaml 5.00 正常建置。

  • ocaml-bench/sandmark#260 為循序執行新增 5.00 分支。修復筆記本。

    Sandmark 現在可以建置新的 5.00 OCaml 變體,以在 CI 中建置循序和並行的效能基準。

  • ocaml-bench/sandmark#261 更新效能基準和 domainslib 以支援 OCaml 4.14.0+domains (OCaml 5.0)

    我們現在可以為 OCaml 5.00 建置 Sandmark 效能基準,而且 PR 更新為使用 domainslib.0.3.2

current-bench

進行中

  • ocurrent/current-bench#219 支援從不同編譯器變體覆蓋圖表

    目前,我們可以查看每個 OCaml 版本的前端圖表。我們需要跨編譯器變體覆蓋圖表,以進行更好的比較和視覺化。

  • ocurrent/current-bench#220 為 nightly 執行設定 current-bench 和 Sandmark

    在調整過的機器上,我們需要為 Sandmark 設定 current-bench(後端和前端),並排程 nightly 執行。

  • ocurrent/current-bench#221 支援 Sandmark 執行的開發人員儲存庫、分支和提交

    要求在 nightly 的基礎上為開發人員分支執行 current-bench,以視覺化每個提交的效能基準結果。

已完成

  • ocurrent/curren-bench#106--privileged 與 Docker run_args 用於 Multicore OCaml

    current-bench master (3b3b31b...) 能夠在 Docker 中執行 Multicore OCaml Sandmark 效能基準,而無需 --privileged 選項。

  • ocurrent/current-bench#146 複製 ocaml-bench-server 設定

    current-bench 現在支援使用自訂的 bench.Dockerfile,可讓您覆寫要與 Sandmark 一起使用的 TAG 和 OCaml 變體。

  • ocurrent/current-bench#190 允許選定的專案在一個以上的 CPU 上執行

    已新增 OCAML_BENCH_MULTICORE_REPOSITORIES 環境變數,以在一個以上的 CPU 核心上建置專案。

  • ocurrent/current-bench#195 新增僅啟動前端和 DB 容器的說明

    已使用僅啟動前端和資料庫容器的說明更新 HACKING.md 檔案。這可讓您在任何機器上執行效能基準,並使用 ETL 指令碼將結果傾印到資料庫中,並在 current-bench 前端中檢視它們。

我們要感謝社群中所有 OCaml 使用者、開發人員和貢獻者對專案的持續支援。請保持安全!

縮寫

  • AFL:American Fuzzy Lop
  • API:應用程式開發介面
  • AST:抽象語法樹
  • AWS:Amazon Web Services
  • CI:持續整合
  • CPU:中央處理單元
  • DB:資料庫
  • DLS:網域本機儲存
  • ETL:擷取轉換載入
  • GC:垃圾收集器
  • IO:輸入/輸出
  • MD:Markdown
  • MLP:ML 檔案預處理
  • OOM:記憶體不足
  • opam:OCaml 套件管理器
  • OS:作業系統
  • PR:提取請求
  • PRNG:虛擬亂數產生器
  • RFC:徵求意見稿
  • WG:工作小組