OCaml 多核 - 2021 年 3 月

欢迎来到 2021 年 3 月的 多核 OCaml 月度报告!以下更新和 之前的更新 由我、@kayceesrk 和 @shakthimaan 共同编撰。我们大体上仍按计划将多核的最后先决条件整合到下一个 (4.13) 版本中,并建议将仅限于域的并行性用于 OCaml 5.0。

上游 OCaml 4.13 开发

复杂的安全点 PR (#10039) 正在取得进展,并不断改进,以减少引入更多轮询点导致的二进制文件大小增加。特别感谢 @damiendoligez 为此投入了 PR-to-the-PR,致力于找到一种可行的算法!

多核 OCaml 树

如果有一件事我们不想再做,那就是 Git 重新基底。多核之旅从 OCaml 4.02 以及 4.044.06 和目前的 4.10 开始,已经过去了很久。我们很高兴地宣布,希望这是最后一次将多核 OCaml 树重新基底到 OCaml 4.12.0,现在已经可用。现在也有一个更简单的命名方案,以更密切地反映我们的上游策略。

  • OCaml 4.12.0+domains 是仅限于域的并行性,将提交用于 OCaml 5.0。
  • OCaml 4.12.0+domains+effects 是包含域并行性和基于效果的并发性的版本。

您可以在 multicore-opam 存储库中找到这些版本的 opam 安装说明。甚至有一个 ocaml-lsp-server 可用,因此您最喜欢的 IDE 应该可以正常工作!

仅限于域的并行性树

本月的大部分工作都集中在域本地分配缓冲区 (DLAB) 的集成和调试上,以及从压力测试和 opam 批量构建中追查边界情况故障。有关详细信息,请参阅下一节中的长 PR 列表。

我们还在清理历史遗留问题,以减少与 OCaml 主干的差异,以便为生成上游集成的 OCaml 5.0 PR 清除路径。

并发性和效果树

现在可以在 arXiv 上获取关于 将效果处理程序移植到 OCaml 的 PLDI 2021 年正式论文。论文中描述的代码可以通过 4.12.0+domains+effects opam 开关使用。请随时将任何意见反馈给 @kayceesrk 和我。

我们还一直在对多核 IO 堆栈进行黑客攻击,并且刚刚开始将并发性 (通过效果) 和并行性 (通过域) 结合到 Linux io_uring、macOS 的 Grand Central Dispatch 和 Windows iocp 中。我们将在接下来的几个月中提供更多相关报告,但 Linux 上的早期基准测试结果令人鼓舞。

CI 和基准测试

我们继续扩展对项目的不同 CI 配置的测试。关于 Sandmark 基准测试,我们正在添加 Irmin layers.ml 基准测试。还有一个使用 OCurrent current-bench 框架的端到端管道,可以为我们提供来自 PR 的基准测试结果,这些结果可以与之前的运行结果进行比较。

与往常一样,我们首先介绍多核 OCaml 更新,然后介绍 Sandmark 基准测试项目的正在进行和已完成的任务。最后,列出上游 OCaml 工作供您参考。

详细更新

多核 OCaml

正在进行

DLAB

  • ocaml-multicore/ocaml-multicore#484 线程分配缓冲区

    该 PR 提供了对线程本地分配缓冲区或 Domain Local Allocation Buffers 的实现。代码审查和更改测试正在进行中。

  • ocaml-multicore/ocaml-multicore#508 域本地分配缓冲区

    这是对 Thread allocation buffers PR 的扩展,包括初始化、全局次要堆大小的延迟调整大小以及重新基底到 4.12 分支。

测试

  • ocaml-multicore/ocaml-multicore#522 使用 -O0 而不是 -O2 构建运行时会导致测试套件失败

    使用 -O0 而不是 -O2 运行时测试失败,这需要进一步调查。

  • ocaml-multicore/ocaml-multicore#526 weak-ephe-final issue468 在次要堆非常小的情况下可能会失败

    使用小的次要堆 (4096 个字) 运行 weak-ephe-final 测试会导致 issue468 测试失败。

  • ocaml-multicore/ocaml-multicore#528 扩展 CI 运行

    扩展我们现有 CI 运行的范围和执行以进行全面测试的一系列要求。

杂项

  • ocaml-multicore/ocaml-multicore#514 更新 ocaml-variants.opam 中的说明

    ocaml-variants.opamconfigure.ac 文件已更新,以使用多核 OCaml 存储库,并使用本地切换而不是全局切换。当前的多核 OCaml 位于 4.12 分支。

  • ocaml-multicore/ocaml-multicore#523 Systhreads Mutex 抛出 Sys_error

    Systhreads Mutex 的错误检查应与主干一致,而不是多核 OCaml 报告的致命错误。

  • ocaml-multicore/ocaml-multicore#527 将 eventlog 移植到 CTF

    eventlog 实现必须移植到通用跟踪格式。日志输出应与 parallel_minor_gc 输出一致,并且需要执行压力测试。

已完成

上游

  • ocaml-multicore/ocaml-multicore#490 从字节码中删除 getmutablefield

    字节码编译器和解释器已更新,删除了 getmutablefield 操作码。

  • ocaml-multicore/ocaml-multicore#496 用 caml_initialize 替换 caml_initialize_field

    一个用于替换 caml_initialize_field 的补丁,该补丁之前与并发次要收集器一起使用,现在已替换为 caml_initialize

  • ocaml-multicore/ocaml-multicore#503 重新启用 lib-obj 和 asmcomp/is_static 测试

    lib-objasmcomp/is_static 测试已重新启用,并且已更新 Multicore NO_NAKED_POINTERS 的配置设置。

  • ocaml-multicore/ocaml-multicore#506Field 替换 Op_val

    Op_val (x)[i] 的使用已替换为 Field (x, i),以与主干实现保持一致。

  • ocaml-multicore/ocaml-multicore#507 更改解释器以使用裸代码指针

    已进行更改以识别解释器堆栈中的裸指针,以与主干兼容。

  • ocaml-multicore/ocaml-multicore#516 删除 caml_root API

    caml_root 变量已更改为 value 类型,并作为世代全局根进行管理。因此,现在删除了 caml_root API。

DLAB

  • ocaml-multicore/ocaml-multicore#511 在主要堆而不是次要堆上分配唯一的根令牌

    唯一的根令牌分配现在在主要堆分配上完成,该分配不会引发任何异常,并且在域创建失败时会干净地退出。

  • ocaml-multicore/ocaml-multicore#513 在调试运行时在收集结束时清除次要堆

    调试值为次要堆的每个元素写入,以调试故障。我们现在在次要收集结束时清除次要堆。

  • ocaml-multicore/ocaml-multicore#519 使计时测试更加健壮

    timing.ml 测试已更新,以更能抵抗使用 DLAB 进行测试。

增强功能

  • ocaml-multicore/ocaml-multicore#477 将 TLS 区域移动到专用内存空间

    为了支持域本地分配缓冲区,我们现在将 TLS 区域移动到其自己的分配内存空间,从而更改我们分配单个域的 TLS 的方式。

  • ocaml-multicore/ocaml-multicore#480 从 STW API 中删除 leave_when_done 及其相关函数

    通过清理 stw_request.leave_when_done 实现,从 caml_try_run_on_all_domains*stw_request 中删除了障碍。

  • ocaml-multicore/ocaml-multicore#481 不要在 gc-roots 测试中在域之间共享数组

    每个域都应该有自己的数组,并且并行全局根测试已使用此更改进行了更新。

  • ocaml-multicore/ocaml-multicore#494 对 unix_fork 进行更强的约束

    我们现在强制实施更强的约束,以便在 unix_fork 时,没有其他域可以与域 0 (caml_domain_alone) 一起运行。

  • ocaml-multicore/ocaml-multicore#515 将 memprof 存根添加到构建和 stdlib 中

    必要的 memprof 函数已添加到构建 stdlib,并添加到为运行时构建 memprof。

延迟更新

修复

  • ocaml-multicore/ocaml-multicore#487 systhreads:在线程启动时将 gc_regs_buckets 及其相关函数设置为 NULL

    指针已在 systhreads/st_stubs.c 中初始化为 NULL,这解决了在运行 Layers 基准测试时观察到的 段错误

  • ocaml-multicore/ocaml-multicore#491 在 fork 后重新初始化子锁

    运行时需要在 fork 后正常运行,此补丁通过正确重置域锁来修复此问题。

  • ocaml-multicore/ocaml-multicore#495 修复终结器孤立问题

    修复了如何合并孤立终结器工作的最终化表。 PR 中也添加了一个测试用例。

  • ocaml-multicore/ocaml-multicore#499 修复回溯展开

    跨回调的堆栈展开不正确,现在已经解决了 caml_next_frame_descriptior 的差异。

  • ocaml-multicore/ocaml-multicore#509 修复字节码中 Continuation_already_taken 异常的错误设置

    一个补丁修复了 Continuation_already_taken 异常,该异常在字节码执行中没有按预期设置。

  • ocaml-multicore/ocaml-multicore#510 更新 principality-and-gadts.ml 中的测试用例

    principality-and-gadts.ml 中的一个更改,以记录与 ocaml/ocaml 中 4.12 分支相比的正确输出。

生态系统

  • ocaml-multicore/multicore-opam#46 与 Multicore 兼容的 ocaml-migrate-parsetree.2.1.0

    ocaml-migrate-parsetree 包使用效果语法,现在可以使用 Multicore OCaml 的 parallel_minor_gc 分支进行构建。

  • ocaml-multicore/multicore-opam#47 与 Multicore 兼容的 ppxlib

    效果语法已添加到 ppxlib,现在也与 Multicore OCaml 兼容。

  • ocaml-multicore/multicore-opam#49 4.12 Multicore 配置

    添加了配置以安装 4.12.0+domains+effects4.12.0+domains OCaml 变体。

  • ocaml-multicore/ocaml-multicore#473 在 musl 上构建需要动态链接的 execinfo

    已将允许在基于 musl 的环境中安装 Multicore OCaml 的 opam 文件添加到存储库中。

  • ocaml-multicore/ocaml-multicore#482 检查 -lexecinfo 以便在 musl/alpine 上构建

    已添加一个 configure 脚本,用于检查 -lexecinfo 以支持在 musl/alpine 上构建 Multicore OCaml。

文档

杂项

基准测试

正在进行

  • ocaml-bench/sandmark#204 将 layers.ml 添加为 Sandmark 的基准测试

    包括 Irmin layers.ml 基准测试,并更新其所有依赖项要求。

  • ocaml-bench/sandmark#209 使用规则目标 kronecker.txt 并从 macro_bench 中删除

    已对 graph500seq kernel1.ml 实现进行了审查,并提出了代码更改。macro_bench 标签将保留用于 graph500 基准测试。

  • ocaml-bench/sandmark#212 增加一些基准测试的主要堆分配

    正在进行的工作,以添加更多涉及主要堆分配的长时间运行的基准测试。一些参数已更新为更高的值,并且还添加了更多循环。

  • 我们现在已将 Sandmark 2.0 的构建与 current-bench 集成以用于 CI。基准测试运行的结果现在被推送到 PostgreSQL 数据库,如下所示

    docker=# select * from benchmarks;
    -[ RECORD 1 ]--+-------------------------------------------------------
    run_at         | 2021-03-26 11:21:20.64
    repo_id        | local/local
    commit         | 55c6fb6416548737b715d6d8fde6c0f690526e42
    branch         | 2.0.0-alpha+001
    pull_number    | 
    benchmark_name | 
    test_name      | coq.BasicSyntax.v
    metrics        | {"maxrss_kB": 678096, "time_secs": 101.99969387054443}
    duration       | 00:37:52.776357
    -[ RECORD 2 ]--+-------------------------------------------------------
    run_at         | 2021-03-26 11:21:20.64
    repo_id        | local/local
    commit         | 55c6fb6416548737b715d6d8fde6c0f690526e42
    branch         | 2.0.0-alpha+001
    pull_number    | 
    benchmark_name | 
    test_name      | thread_ring_lwt_mvar.20_000
    metrics        | {"maxrss_kB": 8096, "time_secs": 2.6146790981292725}
    duration       | 00:37:52.776357
    ...
    

    我们将继续努力为 current-bench 添加更多工作流和功能以支持 Sandmark 构建。

已完成

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

    已将 benchclean 目标添加到 Makefile 中,以删除生成的基准测试及其结果,同时保留 _opam 文件夹。

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

    Sandmark 现在支持使用 ITER 变量,并且您可以运行基准测试的多次迭代。例如,使用 ITER=2,将创建几个 .bench 摘要文件,其中包含基准测试结果,如下所示

    $ TAG='"run_in_ci"' make run_config_filtered.json
    $ ITER=2 RUN_CONFIG_JSON=run_config_filtered.json make ocaml-versions/4.10.0+multicore.bench 
    
    $ ls _results/
    4.10.0+multicore_1.orun.summary.bench  4.10.0+multicore_2.orun.summary.bench
    
  • ocaml-bench/sandmark#208 修复 simple-tests/capi 的参数

    run_config.json 中的一个小修复,以正确地将参数传递给 simple-tests/capi 基准测试执行。您可以使用以下命令验证相同的内容

    $ TAG='"lt_1s"' make run_config_filtered.json
    $ RUN_CONFIG_JSON=run_config_filtered.json make ocaml-versions/4.10.0+multicore.bench
    
  • ocaml-bench/sandmark#210 不要在全局根并行基准测试中共享数组

    一个补丁,用于在并行基准测试的全局根实现中不共享数组。

  • ocaml-bench/sandmark#213 解决 4.12.1+trunk、4.12.0+domains 和 4.12.0+domains+effects 的依赖关系

    dependencies/packages 现在已更新,能够使用 Sandmark 构建 4.12.1+trunk4.12.0+domains4.12.0+domains+effects 分支。

OCaml

正在进行

  • ocaml/ocaml#10039 安全点

    正在对安全点 PR 进行审查。特别感谢 Damien Doligez 对安全点和插入轮询的 代码建议。在优化方面还有工作要做。

非常感谢社区中所有 OCaml 用户、开发人员和贡献者对该项目的支持。注意安全!

缩略语

  • API:应用程序编程接口
  • CI:持续集成
  • CTF:通用跟踪格式
  • DLAB:域本地分配缓冲区
  • GC:垃圾收集器
  • OPAM:OCaml 包管理器
  • PR:拉取请求
  • STW:停止世界
  • TLS:线程本地存储