OCaml 多核 - 2021年10月

欢迎阅读 2021 年 10 月的 多核 OCaml 月度报告!此更新以及 之前的更新 由我、@ctk21、@kayceesrk 和 @shakthimaan 共同整理。

正如 @octachron 上个月宣布的那样,核心团队已 承诺明年发布 OCaml 5.0,其中包含多核和效果运行时。本月,我们的多核代码库中出现了大量的活动,以准备一个对上游友好的版本,并进行了一些更改,使代码准备好用于 ocaml/ocaml 并减少差异的大小。回想一下,自从 OCaml 4.09 开始,我们就一直在稳步地引入与多核相关的更改,因此我们现在只剩下一些非常大的部分。因此,主线 OCaml 主干代码现在正在持续合并到我们的 5.00 暂存分支中,并且测试覆盖率也相应地提高了。

在标准库中,我们继续致力于默认情况下提高线程安全性。由于效果处理程序也已确认将进入 5.0,因此它们现在在 stdlib 中也有了自己的模块。多核库生态系统也随着支持 OCaml 5.00 的更改而发展,特别是,随着更多用例的积累,Domainslib 进行了重大更新和改进。Sandmark 性能测试工具与 current-bench 的集成也正在积极进行中。

我们要感谢以下人员的贡献

  • Török Edwin 能够重现 Task.pool 管理中的错误 Domainslib#43,并且还提供了一个 PR 来修复它。
  • Sid Kshatriya 为 Eio 创建了 PR#83 以使用效果处理程序模块。

我们 11 月份的重点将继续放在不懈地构建 5.0 暂存树上,并且我们正在准备与 OCaml 核心团队进行一系列工作组(持续整整一周)以对完整的补丁集进行初步代码审查。请关注 12 月初的结果!

与往常一样,首先列出的是多核 OCaml 更新,其中包含上游工作、与主干的合并、测试用例的更新、错误修复和文档改进。接下来是 Domainslib、TezosEio 的生态系统更新。最后列出 Sandmark 和 current-bench 任务以供参考。

多核 OCaml

正在进行

上游

测试套件

  • ocaml-multicore/ocaml-multicore#656 Core 测试套件工作流程

    一个实现工作流程的草稿 PR,每天运行一次 Core 的测试套件。

  • ocaml-multicore/ocaml-multicore#720 提高 ephemerons 与测试套件的兼容性

    该 PR 导入上游修复程序以使 ephemerons 与中缀对象一起使用,并为 weaktest.ml 提供修复程序。

  • ocaml-multicore/ocaml-multicore#722 测试套件:重新启用 signals_alloc 测试用例

    signals_alloc 测试用例已启用,并且该 PR 还尝试确保字节码解释器轮询信号。

  • ocaml-multicore/ocaml-multicore#723 GitHub Action MacOS 运行程序上的 beat.ml 失败

    对 CI 执行运行的测试套件中 beat.ml 测试失败进行调查。

其他

  • ocaml-multicore/ocaml-multicore#669 为域设置线程名称

    一个为多核 OCaml 实现线程命名的补丁。它提供了一个接口,可以以不同的方式命名域和线程。

  • ocaml-multicore/ocaml-multicore#698 将空闲池返回给操作系统

    pool_release 位于 shared_heap 中,不会将内存返回给操作系统。关于保留多少内存以及使用空间开销设置回收多少内存的持续讨论。

  • ocaml-multicore/ocaml-multicore#703 当没有域可以处理阻塞信号时,caml_enter_blocking_section 中可能存在循环

    当存在阻塞特定信号集的域且没有其他域可以处理该信号时,可能会触发这种情况,并且可能是由 caml_enter_blocking_section 中的循环引起的。

  • ocaml-multicore/ocaml-multicore#725 阻塞信号无限循环修复

    已引入单调 recorded_signals_counter 以修复当没有域可以处理阻塞信号时 caml_enter_blocking_section 中可能存在的循环。

  • ocaml-multicore/ocaml-multicore#726 并发修改对象的编组是不安全的

    必须正确处理在不同域上被修改的对象的编组,并且应该是安全的。它不应导致分段错误或崩溃。

已完成

上游

构建
  • ocaml-multicore/ocaml-multicore#662 在 5.0 上禁用更改检查

    .github/workflows/hygiene.yml 已更新为在 5.00 上禁用检查,以避免更改条目中的噪音。

  • ocaml-multicore/ocaml-multicore#676 修复 5.00 安装

    caml/byte_domain_state.tbl 已删除,并且 README.adoc 已重命名为 README.stock.adoc,以便使用 OCaml 5.00 分支干净地构建。

更改
  • ocaml-multicore/ocaml-multicore#675Bytes.unsafe_of_string / Bytes.unsafe_to_string 与 OCaml 主干对齐

    bytecomp/bytegen.ml 中使用的 Pbytes_to_string / Pbytes_of_string 现在与上游 OCaml 对齐。

  • ocaml-multicore/ocaml-multicore#677 删除调试 nop

    调试 nop 原语对于上游来说不是必需的,并且已被清理。该 PR 还修复了 emit.mlp 中 check-typo 的空格,使其与主干匹配。

  • ocaml-multicore/ocaml-multicore#679 删除 caml_read_field

    caml_read_field 的使用已被删除,因为现有的 Field 提供了所有必要的信息,使其更接近上游 OCaml。

  • ocaml-multicore/ocaml-multicore#681 回退到 otherlibs/unix 的 ocaml/trunk 版本

    unixsupport.ccstringv.cotherlibs/unix 中的文件已更新,使其类似于 ocaml/ocaml

  • ocaml-multicore/ocaml-multicore#684 删除 lambda/matching 中的历史 for_handlerReperform_noloc

    lambda/matching.ml{,i} 中的 for_handler 函数和 Reperform_noloc 不需要上游,因此已被删除。

  • ocaml-multicore/ocaml-multicore#685 从 interp.c 中删除 Init_field

    interp.c 文件已更新,使其更接近 ocaml/ocaml。已修复 check-typo 错误,并且 Init_field 宏已被清理。

  • ocaml-multicore/ocaml-multicore#704 从 Domain 中删除 Sync.poll 和纳秒

    Domain 模块已更新,仅包含上游所需的变化。Domain.Sync.pollDomain.nanosecond 已删除。Domain.Sync.cpu_relax 已重命名为 Domain.cpu_relaxplatform.h 已更新,其中包含 check-typo 的修复程序。

  • ocaml-multicore/ocaml-multicore#706otherlibs/win32unix 回退到 ocaml/trunk

    otherlibs/win32unix/* 文件已更新,使其更接近 ocaml/ocaml

  • ocaml-multicore/ocaml-multicore#708 删除 maybe stats

    输出统计信息的 caml_maybe_print_stats 原语和 OCAMLRUNPARAMs 选项现已删除。

  • ocaml-multicore/ocaml-multicore#724 运行时:从 io.h 中删除未使用的字段

    runtime/caml/io.h 中删除 revealedold_revealed,因为它们也已从 ocaml/ocaml 中删除。

差异
合并
  • ocaml-multicore/ocaml#2 将 trunk 更新到最新的上游 trunk

    此 PR 旨在帮助解决 OCaml 5.0 的差异输出问题。通过这些更改,您可以成功执行 make && make tests。结果摘要如下所示

    Summary:
    2918 tests passed
     40 tests skipped
      0 tests failed
    105 tests not started (parent test skipped or failed)
      0 unexpected errors
    3063 tests considered
    
    
  • ocaml-multicore/ocaml#3 最新的 5.00 提交

    trunk 的最新提交现已合并到 ocaml-multicore 5.00 分支。

  • ocaml-multicore/ocaml-multicore#718 弃用 Domain 中的 Sync 和 timer_ticks

    此补丁将 4.12.0+domains+effects 的更改与主线 5.00 分支同步。

线程安全

  • ocaml-multicore/ocaml-multicore#632 Str 模块的多域安全性

    PR#635 使 lib-str 域安全,以便与 Multicore OCaml 并发工作。

  • ocaml-multicore/ocaml-multicore#672 Codefrag 线程安全性

    此 PR 引入了一个无锁跳表,使 codefrag 线程安全。代码片段不能在移除后立即释放,但会被添加到一个列表中,并在稍后的停止世界暂停期间清理。

修复

测试套件

文档

  • ocaml-multicore/ocaml-multicore#672 修复 major_gc 的拼写检查错误,以避免 #672 中的更改被覆盖

    一个修复 runtime/major_gc.c 中拼写检查错误的补丁。

  • ocaml-multicore/ocaml-multicore#696 Stdlib:修复 effectHandlers.mli 中的拼写错误

    已修复 stdlib/effectHandlers.mli 中的一些拼写错误。

  • ocaml-multicore/ocaml-multicore#697 删除死代码并清理次要 GC 中的注释

    一个非功能性更改,用于清理次要和主要 GC 文件中的注释。

  • ocaml-multicore/ocaml-multicore#699 清理 fiber 实现并添加文档

    已删除 amd64.S 中未使用的代码并修复了格式。不再需要在堆栈顶部添加 24 字节以进行外部调用,并且已将其删除。

  • ocaml-multicore/ocaml-multicore#713 阐明 Lazy 关于 RacyLazy 和 Undefined 异常的文档。

    已更新 stdlib/lazy.mli 中的文档,以阐明 try_force 的行为和线程安全性。

  • ocaml-multicore/ocaml-multicore#717 严格化 minor_gc.c 中的代码注释

    此 PR 解释了如何提升 ephemeron 密钥以避免引入屏障,并使用 /* ... */ 样式的注释。

  • ocaml-multicore#docs 文档

    OCaml 5.00 的文档存储库,其中包含设计和建议的上游计划。

效果处理程序

杂项

生态系统

正在进行
Domainslib
  • ocaml-multicore/domainslib#43 Task.pool 管理中可能存在错误

    Török Edwin 使用 4.12.0+domains 和 AMD Ryzen 3900X CPU 上的 domainslib 0.3.1 重现了分段错误,并且还提供了一个带有修复程序的草稿 PR!

  • ocaml-multicore/domainslib#46 提供一种遍历所有池的方法

    需要能够遍历 domainslib 中创建的所有池。一个用例是拆除所有池。可以使用弱哈希集来存储指向池的弱指针。

  • ocaml-multicore/domainslib#47 Task.await 死锁(任务已完成但 await 永远不会返回)

    关于在 Task.async 内部嵌套 Task.await 以及在 Task.async 内部嵌套 Task.async 的查询。还提供了一个代码片段、堆栈跟踪和平台信息来重现死锁场景。

  • ocaml-multicore/domainslib#48ws_deque 移动到 lockfree

    请求将 domainslib 中的工作窃取双端队列移动到 ocaml-multicore/lockfree,并使 domainslib 依赖于此新的 lockfree 实现。

  • ocaml-multicore/domainslib#49 我们是否应该从库中公开多通道?

    关于 Multicore OCaml 用户是否会发现非 FIFO 多通道实现有用的查询。Domainslib 已经提供了 FIFO 通道。

  • ocaml-multicore/domainslib#50 Multi_channel:允许每个程序使用不同配置创建多个实例

    Török Edwin 在 lib/multi_channel.mllib/task.ml 中贡献了一个草稿 PR,用于删除使用全局密钥并改用每个通道密钥。

  • ocaml-multicore/domainslib#51 利用效果处理程序

    任务现在使用效果处理程序创建,并且新的 test_deadlock.ml 测试了相同的功能。此更改仅适用于 4.12+domains5.00。来自图灵机(Intel Xeon Gold 5120 CPU @ 2.20 GHz,28 个隔离核心)的性能结果如下所示

    Domainslib-PR-51-performance

杂项
  • ocaml-multicore/tezos#8 ci.Dockerfile 抛出警告

    Ubuntu 20.10 上的 ci.Dockerfile 在使用 GCC 10.3.0 时会对 _Atomic 抛出 C99 警告。

  • ocaml-multicore/tezos#10 修复 make build-deps,修复 NixOS 支持

    conf-perl 在上游不再需要,并且已从 tezos-opam-repository 中删除。此补丁还修复了 make build-deps/build-dev-deps

  • ocaml-multicore/ocaml-uring#39 NixOS 上的测试失败

    ocaml-uring 主分支在 NixOS 上使用 dune runtest 显示测试失败。

  • ocaml-multicore/eio#85 有计划支持js_of_ocaml吗?

    Konstantin A. Olkhovskiy(Lupus)询问 EIO 是否可以编译到 JavaScript 后端,假设js_of_ocaml 支持 effects。

已完成
Domainslib
  • ocaml-multicore/domainslib#45 添加命名池

    现在在设置期间添加了一个可选参数来命名池。此名称可用于稍后检索池。

  • ocaml-multicore/domainslib#52 使用随机数作为缓存前缀以在 CI 中禁用缓存

    现在在.github/workflows/main.yml中,cache-prefix 使用随机数来在 CI 中禁用缓存。

  • ocaml-multicore/domainslib#53 在 PR#704 之后使 domainslib 能够使用 OCaml 5.00 构建/运行

    CI 已更新,现在可以使用 OCaml 5.00 分支进行构建和运行。

  • ocaml-multicore/domainslib#54 使用最新的 4.12+domains+effects 哈希值作为缓存键

    缓存键现在使用来自 OCaml Multicore 的最后一个提交哈希值,以便在 CI 中使缓存失效。

其他
  • ocaml-multicore/tezos-opam-repository#3 添加 domainslib

    domainslib.0.3.1 版本现在已作为软件包包含在 Tezos OPAM 存储库中。

  • ocaml-multicore/tezos-opam-repository#5 上游更新

    Tezos OPAM 存储库 已使用上游更改进行了更新,使用了PR#1PR#5

  • ocaml-multicore/retro-httpaf-bench#17 改善图表

    现在已在从 Jupyter notebook 生成的图表中添加了标记,以便轻松区分颜色线条。

    retro-httpaf-bench-17-graph|690x409

  • ocaml-multicore/multicore-opam#59 在 ocaml-multicore/ocaml-multicore#514 之后修复 batteries

    batteries-includedbatteries.3.3.0+multicore opam 文件已使用正确的 src URL 进行更新。

  • ocaml-multicore/eio#82 迁移到 4.12.0+domains effects 实现(无语法 effects 版本)

    此 PR 更新了 eio 以支持 OCaml 5.0 版本的 effects 实现。

  • ocaml-multicore/eio#83 Effect 处理程序现在有自己的模块

    Sid Kshatriya 贡献了一个补丁,将 Obj.Effect_handlers 重命名为 EffectHandlers,因为 effect 处理程序在 Stdlib 中有自己的模块。

  • ocaml-multicore/core

    Jane Street 的标准库覆盖层 core 现在已添加到 ocaml-multicore GitHub 项目存储库中。

基准测试

Sandmark

正在进行

  • ocaml-bench/sandmark#248 Coq 构建失败

    一个新的 Coq tarball,coq-multicore-2021-09-24,可以使用 Multicore OCaml 4.12.0+domains 构建,但是,stdio.v0.14.0 无法使用 4.14.0+trunk 顺利构建,因为存在已报告的dune 问题

  • ocaml-bench/sandmark#260 添加用于顺序运行的 5.00 分支。修复笔记本。

    一个新的 5.00 OCaml 变体分支已添加到 Sandmark,以跟踪 CI 中的顺序基准运行。

已完成

  • ocaml-bench/sandmark#256 删除旧变体

    旧变体 4.05.*4.06.*4.07.*4.08.*4.10.0.* 现已从 Sandmark 中删除。

  • ocaml-bench/sandmark#258
    在 README 中记录 Makefile 变量

    README 现在包含有关在 Sandmark 中构建和执行基准测试期间使用的各种 Makefile 变量的文档。

current-bench

正在进行

  • ocurrent/current-bench#117 从 Docker 容器读取 stderr

    出于调试目的,我们希望查看 Docker 容器内基准执行的任何构建失败。

  • ocurrent/current-bench#146 复制 ocaml-bench-server 设置

    需要将 TAG 和 OCaml 变体从 Sandmark Makefile 抽象到 current-bench,以便能够为不同的编译器版本和开发者分支运行基准测试。

已完成

  • ocurrent/current-bench#105 将 Docker 镜像名称从 pipeline/lib/pipeline.ml 抽象到环境中

    现在支持自定义 Dockerfile,因此您可以在 Dockerfile 中提取任何 opam 镜像。

  • ocurrent/current-bench#119 OCAML_BENCH_DOCKER_CPU 不支持用于并行执行的 CPU 范围

    Docker CPU 设置现在使用字符串表示而不是整数来指定用于并行执行的 CPU 列表。

  • ocurrent/current-bench#151 Docker 与本地性能

    使用 current-bench 的 Docker 以及本地顺序和并行基准运行在禁用超线程的情况下没有显示出明显的差异。下面提供了 Gödel 服务器配置和 Sandmark-nightly notebook 图表结果以供参考

    • CPU:Intel(R) Xeon® Gold 5120 CPU @ 2.20 GHz
    • OS:Ubuntu 20.04.3 LTS (Focal Fossa)
    • Sandmark 2.0-beta 分支:https://github.com/ocaml-bench/sandmark/tree/2.0-beta
    • 已禁用超线程
      $ cat /sys/devices/system/cpu/smt/active
      0
      
    • 内存 (62 GB),磁盘 (1.8 TB)。
    • OCaml 变体:4.12.0+domains
    • Sandmark-nightly 笔记本:https://github.com/ocaml-bench/sandmark-nightly/tree/main/notebooks
    • 每个基准测试五次迭代的平均值
      • run_in_ci 用于顺序
      • macro_bench 用于并行

    时间 Current-bench-151-Time|690x236 标准化 Current-bench-151-Time-Normalised|690x315 堆顶词 Current-bench-151-Top-heap-words|690x236 标准化 Current-bench-151-Top-heap-words-Normalised|690x323

    MaxRSS (KB) Current-bench-151-MaxRSS|690x237 标准化 Current-bench-151-MaxRSS-Normalised|690x325

    主要收集 Current-bench-151-Major-collections|690x236 标准化 Current-bench-151-Minor-collections-Normalised|690x320

    并行基准测试 Current-bench-151-Parallel-benchmarks-I|486x500 Current-bench-151-Parallel-benchmarks-II|237x500

(请参阅 PR 全文以获取完整的图表集,包括主要词语和花费的时间)

我们特别感谢社区中所有 OCaml 用户、开发人员和贡献者,感谢他们宝贵的时间和对项目的持续支持。请注意安全!

缩略语

  • AMD:超微半导体公司
  • CI:持续集成
  • CPU:中央处理器
  • DLS:域本地存储
  • FIFO:先进先出
  • GB:千兆字节
  • GC:垃圾回收器
  • GCC:GNU 编译器集合
  • IO:输入/输出
  • OPAM:OCaml 包管理器
  • OS:操作系统
  • PR:拉取请求
  • TB:太字节
  • URL:统一资源定位符