OCaml 多核 - 2021 年 1 月

欢迎来到双份的多核月刊,其中包含 2020 年 12 月和 2021 年 1 月的捆绑内容(团队集体崩溃到年底休息,以获得应得的休息)。我们鼓励您查看所有 以前的每月 更新,这些更新由 @shakthimaan、@kayceesrk 和我整理。

回顾 2020 年,我们在将多核 OCaml 上游方面取得了许多重大里程碑。主要亮点包括:实施事件日志跟踪系统,使复杂并行性的调试变得实用;从 OCaml 4.06 到 4.11 的巨大重新定位;关于并行编程的一章;在 ICFP 2020 上发表“将并行性移植到 OCaml”;Sandmark 基准测试的生产使用;以及系统线程集成的实现。在所有这些都在多核代码树中发生的同时,上游到 OCaml 主线的努力也全面展开,@xavierleroy 领导着核心团队的努力,以确保将合适的部件集成到 OCaml 的各个版本中,并且具有与任何其他功能相同的广泛代码审查。

2020 年底,生态系统库得到了增强和更新,更多工具变得可用。特别是,我们要感谢

  • @mattpallissard 使 merlindot-merlin-reader 与多核 OCaml 4.10 协同工作。这使得使用 OCaml 平台工具(如 VSCode 插件)进行编程变得更加愉快。
  • @eduardorfs 使用 ReasonML 项目测试了 no-effect-syntax 多核 OCaml 分支。

@kayceesrk 还在线发表了几次公开演讲

我们非常感谢 OCaml 核心开发人员在 2020 年为这项工作投入了大量的时间和精力!我们正在制定 2021 年激动人心的多核路线图的更广泛计划,该计划将在核心 OCaml 开发人员会议很快批准后,包含在下一个月报中。总体策略保持一致:将功能部件稳定地放置到每个即将发布的 OCaml 版本中,以便每个部件都可以独立地进行审查和测试,这将先于 OCaml 5.0 版本,该版本将包含域并行性。

随着 OCaml 4.12 的 beta 版本发布,我们 1 月份主要花时间处理 OCaml 4.13 所需的一些重要部件。特别是,安全点 PR 已经过了一次重大更新(以及相应的性能改进),并且我们一直在设计和实现域本地分配缓冲区 (DLAB)。我们还开始研究如何将出色的顺序最佳拟合分配器与我们的多核主要 GC 合并,以便在 OCaml 5.0 中获得两全其美。多核 IO 堆栈也已重新开始开发,重点是 Linux 的新 io_uring 内核接口,然后再改造旧的稳固的 epollkqueue 接口。

在工具方面,多核 Merlin 支持在 12 月份开始,现在已经合并,感谢 @mattpallissard 和 @eduardorfs。我们继续致力于为即将发布的 alpha 版本的 Sandmark 2.0 基准测试套件进行增强,@shakthimaan 为多核团队举办了一个关于这些改进的在线研讨会,该研讨会已经录制,并将包含在下一个月报中,供任何有兴趣为我们的基准测试工作做出贡献的人。

与之前的报告一样,多核 OCaml 更新首先列出 2020 年 12 月,然后是 2021 年 1 月。上游 OCaml 的持续工作最后被提及,供您参考,在多核树特定部分之后。

2020 年 12 月

多核 OCaml

持续进行

生态系统

  • ocaml-multicore/lockfree#6 当前状态和潜在改进

    一个 RFC,列出了 lockfree 库的当前状态,以及 Kcas 依赖项、测试套件和基准测试的潜在性能改进。

  • ocaml-multicore/lockfree#7 设置 travis CI 构建

    需要为 CI 构建系统创建一个类似于 https://github.com/ocaml-multicore/domainslib/ 中的 .travis.yml 文件。

  • ocaml-multicore/effects-examples#20 添加 WebServer 示例

    一项开放的任务,将基于 httpaf 的 Web 服务器实现添加到 effects-examples 存储库中。

  • ocaml-multicore/effects-examples#21 调查 CI 故障

    CI 构建在 MacOS 上超时失败,但在 Linux 上运行正常。正在进行调查。

  • ocaml-multicore/multicore-opam#39 多核 Merlin

    感谢 @mattpallissard (Matt Pallissard) 和 @eduardorfs (Eduardo Rafael) 测试 merlindot-merlin-reader,并使它与多核 OCaml 4.10 协同工作!它也已经在 VSCode 和 Atom 上进行了测试,下面显示了 UI 的屏幕截图。 PR 39 多核 Merlin 屏幕截图|435x350

API

  • ocaml-multicore/ocaml-multicore#448 在 C API 中重新引入 caml_stat_accessors

    caml_stat_minor_wordscaml_stat_promoted_wordscaml_allocated_words caml_stat_minor_collections 字段在多核 OCaml 中没有公开。这是一个讨论,以解决对这些字段的可能解决方案。

  • ocaml-multicore/ocaml-multicore#459 将 caml_root API 替换为全局根

    一项正在进行的工作,将类型为 caml_root 的变量转换为 value,并将它们注册为全局根或世代全局根,以完全删除 caml_root API。

杂项

  • ocaml-multicore/ocaml-multicore#450 “流氓”系统线程和域终止

    一个 RFC,讨论了非空线程链的域终止语义。在多核 OCaml 中,域终止并不意味着程序结束,而插槽重用增加了实现的复杂性。

  • ocaml-multicore/ocaml-multicore#451 OCaml 5.0 说明:删除 compatibility.h

    OCaml Multicore 从 compatibility.h 中删除了 modifyinitialize,这是一个跟踪问题,用于在 OCaml 5.0 中删除 compatibility.h。

  • ocaml-multicore/ocaml-multicore#458 no-effect-syntax:从 typedtree 中删除效果

    该 PR 从 typedtree.ml 中删除了效果语法使用,并使使用 AST 的外部应用程序能够与仅包含域的多核 OCaml 协同工作。

  • ocaml-multicore/ocaml-multicore#461 从事件日志中删除 stw/leader_collision 事件

    一个补丁,通过删除 stw/leader_collision 日志消息来使查看和分析日志变得更好。

已完成

  • ocaml-multicore/effects-examples#23 迁移到 dune

    构建脚本使用 OCamlbuild,现在已移植到使用 dune。

  • ocaml-multicore/ocaml-multicore#402 将 handle_gc_interrupt 拆分为处理远程和轮询部分

    该 PR 包括添加 caml_poll_gc_work,其中包含在 caml_handle_gc_interrupt 中执行的 GC 工作轮询。这有助于递归处理中断,而不会引入新的状态。

  • ocaml-multicore/ocaml-multicore#439 系统线程生命周期工作

    改进修复了当两个域正在初始化时 caml_thread_scan_roots 中的竞争条件,并且已经重新设计了工作,以改善一般资源处理和描述符和堆栈的释放。

  • ocaml-multicore/ocaml-multicore#446 在次要收集结束时收集 GC 统计信息

    GC 统计信息是在次要收集结束时收集的,并且已删除 GC 采样统计信息的双缓冲。根据以下插图,此更改不会影响观察到的现有基准测试运行结果,与库存 OCaml 相比。

    PR 446 Graph Image|690x317

  • ocaml-multicore/ocaml-multicore#454 在 amd64 中尊重 ASM_CFI_SUPPORTED 标志

    amd64.S 中的 CFI 指令现在受 ASM_CFI_SUPPORTED 保护,因此使用 --disable-cfi 进行编译现在将提供干净的构建。

  • ocaml-multicore/ocaml-multicore#455 在 fork 上没有阻塞部分

    一个补丁,用于处理流氓线程尝试接管线程 masterlock 的情况,以及防止子线程移至无效状态。现在可以安全地在多核 OCaml 中使用 Dune。

基准测试

持续进行

  • ocaml-bench/rungen#1 修复编译器警告和错误以进行干净构建

    该补丁提供了对 rungen 的细微修复,以便使用 dune 进行干净构建,用于 Sandmark 2.0。

  • ocaml-bench/orun#2 修复编译器警告和错误以进行干净构建

    已删除未使用的变量和函数,以删除在使用 dune 构建 orun 时产生的所有警告和错误。

  • ocaml-bench/sandmark#198 Sandmark 中的噪声

    一个 RFC,用于测量基准测试的多次执行运行之间的噪声,以更好地了解使用各种硬件配置设置以及 ASLR 打开和关闭时的性能。

  • ocaml-bench/sandmark#200 全局根微基准测试

    该补丁包括 globroots_seq.mlglobroots_sp.mlglobroots_mp.ml,这些文件添加了微基准测试,用于测量全局根扫描的效率。

  • 我们正在继续将现有的 Sandmark 基准测试套件与 Sandmark 2.0 原生 dune 构建环境集成,以便与 opam 编译器切换环境一起使用。现有的基准测试已移植到同一个环境中,以使用它们各自的 dune 文件。orunrungen 包现在位于单独的 GitHub 存储库中。

已完成

  • ocaml-bench/sandmark#196 根据标签过滤基准测试

    现在可以根据tags 而不是自定义目标 .json 文件来过滤基准测试。现在可以使用以下命令构建基准测试

    $ TAG='"run_in_ci"' make run_config_filtered.json 
    $ RUN_CONFIG_JSON=run_config_filtered.json make ocaml-versions/4.10.0+multicore.bench
    
  • ocaml-bench/sandmark#201 修复 CI 中的编译器版本

    在 .drone.yml 中进行了一个小更新,以便在 CI 中使用ocaml-versions/4.10.0+multicore.bench 用于 4.10.0+multicore+serial。

OCaml

正在进行

  • ocaml/ocaml#9876 不要在处理器寄存器中缓存 young_limit

    此用于在 ARM64、PowerPC 和 RISC-V 端口硬件的寄存器中删除young_limit 缓存的 PR 目前正在审查中。

2021 年 1 月

多核 OCaml

正在进行

  • ocaml-multicore/ocaml-multicore#464 用 Field 替换 Field_imm

    该补丁用来自并发次要收集器的 Field 替换了 Field 立即使用。

  • ocaml-multicore/ocaml-multicore#468 终结器导致多域出现段错误

    一个正在进行的测试用例,其中终结器会导致多域出现段错误。

  • 域本地分配缓冲区 (DLAB) 的设计和实现正在进行中,有关 DLAB 的相关说明可在以下DLAB Wiki 中找到。

已完成

生态系统

  • ocaml-bench/rungen#1 修复编译器警告和错误以进行干净构建

    针对 rungen 使用 dune 进行干净构建以用于 Sandmark 2.0 的一些小修复。

  • ocaml-bench/orun#2 修复编译器警告和错误以进行干净构建

    一个补丁,用于在使用 dune 构建orun 时删除未使用的变量和函数,而不会出现任何警告和错误。

  • ocaml-bench/rungen#2 为 dune-release lint 添加元文件

    dune-release lint 检查现在通过了 rungen 的更改、许可证和对 rungen.opam 文件的更新。

  • ocaml-bench/orun#3 为 dune-release lint 添加元文件

    已添加 CHANGES、LICENSE、README.md 和 orun.opam 文件,以准备 opam.ocaml.org 发布的源代码。

  • ocaml-multicore/multicore-opam#39 多核 Merlin

    感谢 @mattpallissard (Matt Pallissard) 和 @eduardorfs (Eduardo Rafael) 测试了merlindot-merlin-reader,并使其与多核 OCaml 4.10 协同工作!这些更改与 VSCode 和 Atom 兼容。相应的PR#40 现已合并。

  • ocaml-multicore/ocaml-multicore#45 Merlin 和 OCaml-LSP 安装说明

    README.md 文件已更新,其中包含使用 Merlin 和 OCaml LSP 服务器的安装说明。

杂项

  • ocaml-multicore/ocaml-multicore#458 no-effect-syntax:从 typedtree 中删除效果

    该 PR 使使用 AST 的外部应用程序能够与仅包含域的多核 OCaml 一起使用,并从typedtree.ml 中删除了效果语法使用。

  • ocaml-multicore/ocaml-multicore#461 从事件日志中删除 stw/leader_collision 事件

    stw/leader_collision 日志消息已清理,使其更易于查看和分析日志。

  • ocaml-multicore/ocaml-multicore#462 从 Travis 转移到 GitHub Actions

    持续集成构建现在已更新为使用 GitHub Actions 而不是 Travis CI,以便与上游 CI 相似。

  • ocaml-multicore/ocaml-multicore#463 次要 GC:将全局根扫描限制到一个域

    活动域在次要收集期间扫描所有全局根,该补丁将全局根扫描限制为仅一个域。以下是顺序和并行宏基准测试结果

PR 463 OCaml Multicore Sequential |690x318

PR 463 OCaml Multicore Parallel |690x458

  • ocaml-multicore/ocaml-multicore#467 禁用标记堆栈的修剪

    一个 PR,用于禁用标记堆栈溢出,以解决当另一个域重标记池时发生的并发错误,而该域也进行分配。

基准测试

正在进行

  • ocaml-bench/sandmark#202 在 Makefile 中添加 bench clean 目标

    已向 Makefile 添加了一个benchclean 目标,以仅删除_build_results_opam 文件夹将保留,其中包含已安装的必需软件包和依赖项,以便可以快速重新构建和执行基准测试。

  • ocaml-bench/sandmark#203 实现 ITER 支持

    已正确实现 ITER 的使用,其中构建了基准测试的多个实例,并重复执行基准测试。这有助于从多个运行中获取指标的平均值。例如,使用 ITER=2 会生成两个.summary.bench 文件,如下所示

    $ ls _build/
      4.10.0+multicore_1  4.10.0+multicore_2  log
    
    $ ls _results/
      4.10.0+multicore_1.orun.summary.bench  4.10.0+multicore_2.orun.summary.bench
    
  • ocaml-bench/sandmark#204 将 layers.ml 添加到 Sandmark 作为基准测试

    将 Irmin layers 基准测试及其依赖项包含到 Sandmark 中。这是一项正在进行的工作。

  • 我们正在继续增强 Sandmark 2.0,它使用原生 dune 来构建和执行基准测试,并将使用当前 Sandmark 配置文件进行移植和测试。orunrungen 包已移至各自的存储库。已实现对 .summary.bench 文件的元标头条目的使用、ITER 支持和包覆盖功能。

已完成

  • ocaml-bench/sandmark#200 全局根微基准测试

    已将globroots_seq.mlglobroots_sp.mlglobroots_mp.ml 的实现添加到微基准测试中,以衡量全局根扫描的效率。

OCaml

正在进行

  • ocaml/ocaml#10039 安全点

    对使用序言省略算法的草案安全点实现的更新,现在已重新定位到 trunk。以下显示了在 sherwood(AMD EPYC 7702)和 thunderx(Cavium ThunderX CN8890)上的运行时基准测试结果

    PR 10039 OCaml Sherwood |690x391 PR 10039 OCaml ThunderX |690x389

已完成

  • ocaml/ocaml#9876 不要在处理器寄存器中缓存 young_limit

    该 PR 删除了 ARM64、PowerPC 和 RISC-V 端口硬件的寄存器中young_limit 的缓存。

我们感谢社区中所有 OCaml 用户和开发人员对该项目的持续支持和贡献,我们期待着在 2021 年与大家合作!

缩略语

  • API:应用程序编程接口
  • ARM:高级 RISC 机器
  • ASLR:地址空间布局随机化
  • AST:抽象语法树
  • CFI:调用帧信息
  • CI:持续集成
  • GC:垃圾收集器
  • ICFP:国际函数式编程大会
  • JSON:JavaScript 对象表示法
  • OPAM:OCaml 包管理器
  • PR:拉取请求
  • RFC:请求意见
  • RISC-V:精简指令集计算 - V
  • UI:用户界面