OCaml 多核 - 2020 年 6 月
欢迎来到 2020 年 6 月的 Multicore OCaml 报告!与 之前的更新 一样,非常感谢 @shakthimaan 和 @kayceesrk 收集了 2020 年 6 月份的更新。这是一次增量更新;新读者可能会发现首先浏览之前的帖子会有所帮助。
这个月,上游 OCaml 项目在为多核集成做准备方面取得了巨大的进展,因为 @xavierleroy 和核心团队推动了一系列举措,为 OCaml 项目做好准备,以实现完整的多核功能集。为了反映这一点,从下个月起,我们将为 ocaml-multicore wiki 提供一个状态页面,其中包含我们多核分支和上游 OCaml 项目本身的当前状态。
为什么不是从这个月开始呢?好吧,有好消息也有坏消息。 上个月,我观察到,我们距离大多数 opam 生态系统与多核分支一起工作只有一个 PR 的距离。好消息是我们距离它工作仍然只有一个 PR 的距离,但它是一个不同的 PR :-) 对 Threads
库的改造带来了 一些设计复杂性,因此,与其进行“临时修补”,我们正在集成一个全面的解决方案,该解决方案将与系统线程、域和(最终)纤维一起使用。这项工作花了一些时间才得以完成,我希望能够在几周内向大家更新一个 opam 友好的 OCaml 4.10.0+multicore。
除此之外,多核分支还有一些其他的改进:mingw Windows 支持,调用栈改进,修复 Unix 模块 等等。完整列表将在本次更新的后面部分的详细报告中列出。
Sandmark 基准测试
本月的一个重要里程碑是升级到最新的 dune.2.6.0,以便为 Sandmark 基准测试项目构建 Multicore OCaml 4.10.0。添加了许多新的 OPAM 包,并且现有的包已升级到最新版本。Multicore OCaml 代码库已经看到了持续的性能改进和增强,这可以从报告中提到的各种 PR 中观察到。
我们要感谢
- @xavierleroy 为一系列多核先决条件 PR 做出了贡献,使 stock OCaml 能够为 Multicore OCaml 做好准备。
- @camlspotter 审查并接受了 camlimages 更改,并发布了 Sandmark 所需的 camlimages.5.0.3 版本。
- @dinosaure 更新了 Sandmark 的解压缩测试基准,以便使用 dune.2.6.0 为 Multicore OCaml 4.10.0 构建和运行。
正在编写关于使用任务池、通道部分、包含代码示例的性能分析等主题的多核 OCaml 并行编程章节。我们将向社区提供文档的早期草稿版本,以征求您的宝贵意见。
论文
我们的“将并行性移植到 OCaml”论文已被正式接受参加 ICFP 2020,该会议将于 2020 年 8 月 23 日至 28 日在线举行。论文的 预印本 之前已经发布,并将在一两天内更新为 ICFP 的最终版本。当然,欢迎您在论文发表后随时提出意见和问题。
令人兴奋的是,另一篇与多核相关的论文,关于 Cosmo: A Concurrent Separation Logic for Multicore OCaml,也将在这个会议上发表。
Multicore OCaml 更新首先列在我们报告中,然后是 Sandmark 基准测试项目的改进。最后,提到了对上游 OCaml 的更改,包括正在进行的任务和已完成的任务,供您参考。
Multicore OCaml
正在进行
-
ocaml-multicore/ocaml-multicore#339 多核 OCaml 中域本地存储的提议
一个在 Multicore OCaml 中实现域本地存储的 RFC 提议。请审查这个想法,并分享您的反馈!
-
ocaml-multicore/ocaml-multicore#342 使用域实现线程库
努力为域重新整理 @jhwoodyatt 的线程库实现。
-
ocaml-multicore/ocaml-multicore#357 使用 pthreads 实现系统线程
探索使用 pthreads 实现系统线程的可能性,同时仍然保持与现有解决方案的兼容性。
-
ocaml/dune#3548 Dune 无法识别辅助编译器
ocaml-secondary-compiler
无法使用 dune.2.6.0 安装。这是必需的,因为 Multicore OCaml 无法在没有系统线程支持的情况下构建最新的 dune。
已完成
-
ocaml-multicore/multicore-opam#22 将 dune 更新到 2.6.0
Multicore OPAM 存储库中的 dune 版本现在已更新为使用最新的 2.6.0。
-
ocaml-multicore/ocaml-multicore#338 引入 Lazy.try_force 和 Lazy.try_force_val
Lazy.try_force
和Lazy.try_force_val
函数的实现,用于实现并发惰性抽象。 -
ocaml-multicore/ocaml-multicore#340 修复并发次要 GC 中的 Atomic.exchange
一个补丁,通过
Atomic.get
引入Atomic.exchange
,为memory.c
中的caml_atomic_exchange
提供适当的读屏障,以获得正确的交换语义。 -
ocaml-multicore/ocaml-multicore#343 修复 extcall noalloc DWARF
为
extcall noalloc
发出的 DWARF 信息破坏了回溯,这个 PR 修复了它。 -
ocaml-multicore/ocaml-multicore#345 绝对异常栈
异常栈的表示从相对寻址更改为绝对寻址,结果令人鼓舞。更改后的 Sandmark 串行基准测试结果如下图所示
-
ocaml-multicore/ocaml-multicore#347 默认情况下启用 -Werror
在
configure
中添加了--enable-warn-error
选项,将 C 编译器警告视为错误。 -
ocaml-multicore/ocaml-multicore#353 在 cpu_relax 中轮询中断,无需加锁
首先使用
Caml_check_gc_interrupt
轮询中断,无需加锁,然后继续使用锁处理中断。 -
ocaml-multicore/ocaml-multicore#354 将 Caml_state_field 添加到 domain_state.h
domain_state.h 中的
Caml_state_field
宏定义是 base-v0.14.0 使用 dune.2.6.0 为 Multicore OCaml 4.10.0 构建所必需的。 -
ocaml-multicore/ocaml-multicore#355 另一个无需加锁轮询中断的位置
与 ocaml-multicore/ocaml-multicore#353 类似,另一个使用
Caml_check_gc_interrupt
首先轮询中断,无需加锁。 -
ocaml-multicore/ocaml-multicore#356 域的备份线程
引入
备份线程
,以便在域在内核中被阻塞时执行 GC 并处理服务中断。 -
ocaml-multicore/ocaml-multicore#358 修复 amd64.S 中错误的 CFI 信息
在
runtime/amd64.S
中为caml_call_poll
和caml_allocN
添加缺少的CFI_ADJUST
指令。 -
ocaml-multicore/ocaml-multicore#359 内联 caml_domain_alone
该 PR 使
caml_domain_alone
成为一个内联函数,以提高memory.c
中caml_atomic_cas_field
和其他原子操作的性能。 -
ocaml-multicore/ocaml-multicore#360 并行次要 GC 内联掩码重构
对
parallel_minor_gc
分支的提升路径的内联掩码重构使test_decompress
sandmark 基准测试的性能提高了 3-5%,并且所有其他基准测试的执行指令都减少了。 -
ocaml-multicore/ocaml-multicore#361 标记栈推送工作积分
该 PR 改进了 Multicore 标记工作记账,使其与 stock OCaml 一致。
-
ocaml-multicore/ocaml-multicore#362 当我们没有读屏障时,Iloadmut 不会覆盖 rax 和 rdx
清理代码,在使用
Iloadmut
时释放 OCaml 代码的寄存器rax
和rdx
。
基准测试
正在进行
-
ocaml-bench/sandmark#8 在 Sandmark 中运行编译器变体的能力
在构建编译器变体时,例如
flambda
,指定配置选项的功能对于开发和测试很有用。正在进行这项功能的开发。 -
ocaml-bench/sandmark#107 添加 Coq 基准测试
我们正在继续为 Multicore OCaml 添加更多基准测试到 Sandmark,并正在研究将 Coq 基准测试添加到我们的工具库中!
-
ocaml-bench/sandmark#124 用户可配置的 paramwrapper 添加到 Makefile
可以通过指定
--cpu-list
用于并行基准测试运行来传递PARAMWRAPPER
环境变量作为参数。 -
ocaml-bench/sandmark#131 更新解压缩基准测试
感谢 @dinosaure 更新了解压缩基准测试,以便使用 dune.2.6.0 为 Multicore OCaml 4.10.0 运行它们。
-
ocaml-bench/sandmark#132 更新依赖项包以使用 dune.2.6.0 和 Multicore OCaml 4.10.0
Sandmark 一直运行在 dune.1.11.4 上,为了使用 Multicore OCaml 4.10.0 及更高版本,我们需要升级到最新的 dune.2.6.0,如 Promote dune to > 2.0 中所述。该 PR 更新了 30 多个依赖包,并成功构建了串行和并行基准测试!
已完成
-
camlspotter/camlimages#1 使用 dune-configurator 代替 camlimages 的 configurator
@camlspotter 在接受了 camlimages.opam 的更改后发布了
camlimages.5.0.3
的新版本,以便使用 dune.2.6.0 进行构建。 -
ocaml-bench/sandmark#115 任务 API 移植:LU 分解、Floyd-Warshall、Mandelbrot、Nbody
对列出的基准测试使用
Domainslib.Task
API 的更改已合并。 -
ocaml-bench/sandmark#121 提到 run_all_parallel.sh 脚本的 sudo 访问权限
README.md 文件已更新,包含执行
run_all_parallel.sh
脚本(用于 nightly 构建)所需的sudo
配置步骤。 -
ocaml-bench/sandmark#125 添加 cubicle 基准测试
German PFS
和Szymanski's mutual exclusion algorithm
cubicle 基准测试已包含在 Sandmark 中。 -
ocaml-bench/sandmark#126 更新 ocaml-versions README 以反映 4.10.0+multicore
README 现已更新以反映最新的 4.10.0 Multicore OCaml 编译器及其变体。
-
ocaml-bench/sandmark#129 添加在 CI 中运行并行基准测试的目标
CI 使用的 .drone.yml 文件已更新,以便运行串行和并行基准测试。
-
ocaml-bench/sandmark#130 在 multicore-numerical 中添加缺失的依赖项
domainslib
库已添加到 multicore-numerical 基准测试的 dune 文件中。
OCaml
正在进行
-
ocaml/ocaml#9541 为经过插桩的运行时添加手册页
经过插桩的运行时 已合并到 OCaml 4.11.0 中。该运行时的手册已创建,正在审核中。
已完成
-
ocaml/ocaml#9619 函数闭包的自描述表示
该 PR 提供了一种方式来记录每个函数闭包入口点的环境位置。
-
ocaml/ocaml#9649 新闭包表示的序列化
output_value
序列化器已更新为使用新的闭包表示。input_value
反序列化器不需要更改。 -
ocaml/ocaml#9655 引入类型 Obj.raw_data 和函数 Obj.raw_field、Obj.set_raw_field 来操作堆外指针
该 PR 引入了一个类型
Obj.bits
,以及函数Obj.field_bits
和Obj.set_field_bits
来读写块字段的位表示,以支持无裸指针操作。 -
ocaml/ocaml#9678 使用哈希表重新实现 Obj.reachable_word 以检测共享
caml_obj_reachable_words
现在使用哈希表而不是修改块头的标记位来检测共享。这是 Multicore OCaml 兼容性所必需的。 -
ocaml/ocaml#9680 裸指针和字节码解释器
字节码解释器实现已更新以支持 Multicore OCaml 所需的无裸指针模式操作。
-
ocaml/ocaml#9682 在没有页表的本机代码中处理信号
该补丁使用代码片段表而不是页表查找来让信号处理程序知道信号是否来自 ocamlopt 生成的代码。
-
ocaml/ocaml#9683 globroots.c:适应无裸指针模式
该补丁在无裸指针模式下将堆外指针视为主堆指针,用于全局根管理。
-
ocaml/ocaml#9689 为新的闭包表示提供通用哈希
哈希函数已更新为使用来自 ocaml/ocaml#9619 的最新闭包表示,用于无裸指针模式。
-
ocaml/ocaml#9698 页表即将结束
该 PR 消除了使用无裸指针模式构建时,运行时系统中对页表的一些使用。
感谢社区中所有 OCaml 开发人员和用户的持续支持和对项目的贡献。祝您安全!
缩写
- API:应用程序编程接口
- CFI:调用帧信息
- CI:持续集成
- DWARF:使用属性记录格式进行调试
- GC:垃圾收集器
- ICFP:国际函数式编程大会
- OPAM:OCaml 包管理器
- PR:拉取请求
- RFC:请求意见书