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.04、4.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.opam
和configure.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-obj
和asmcomp/is_static
测试已重新启用,并且已更新 Multicore NO_NAKED_POINTERS 的配置设置。 -
ocaml-multicore/ocaml-multicore#506 用
Field
替换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#501 安全点延迟修复
延迟实现需要了解安全点,并且我们需要区分并行强制执行的递归强制执行的延迟值。这些修复来自 ocaml-multicore#492 和 ocaml-multicore#493。
-
ocaml-multicore/ocaml-multicore#505 添加唯一的域令牌以区分延迟强制执行失败
已添加
caml_ml_domain_unique_token
来处理多个变异器的竞态访问。这修复了 使用域 ID (int) 来标识延迟块的强制执行域问题。
修复
-
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+effects
和4.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-multicore/ocaml-multicore#502 更新自述文件以介绍 4.12+domains+effects 和 4.12+domains
我们已经使用当前的活动分支列表和历史变体的名称更新了自述文件。
-
ocaml-multicore/ocaml-multicore#520 说明 RacyLazy 的注释
stdlib/lazy.mli
中的文档更新,说明了何时引发RacyLazy
和Undefined
。
杂项
-
ocaml-multicore/ocaml-multicore#486 将 no-effects-syntax 同步到 parallel_minor_gc 分支
ocaml-multicore:no-effects-syntax
分支现在与parallel_minor_gc
分支更改保持同步。 -
ocaml-multicore/ocaml-multicore#489 删除 promote_to
promote_to
函数用于并发次要 GC。它不再需要,因此已删除。 -
ocaml-multicore/ocaml-multicore#500 用 caml_modify 替换 caml_modify_field
caml_modify_field
不再需要,已被caml_modify
替换。
基准测试
正在进行
-
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+trunk
、4.12.0+domains
和4.12.0+domains+effects
分支。
OCaml
正在进行
-
正在对安全点 PR 进行审查。特别感谢 Damien Doligez 对安全点和插入轮询的 代码建议。在优化方面还有工作要做。
非常感谢社区中所有 OCaml 用户、开发人员和贡献者对该项目的支持。注意安全!
缩略语
- API:应用程序编程接口
- CI:持续集成
- CTF:通用跟踪格式
- DLAB:域本地分配缓冲区
- GC:垃圾收集器
- OPAM:OCaml 包管理器
- PR:拉取请求
- STW:停止世界
- TLS:线程本地存储