OCaml 多核 - 2020年3月

多核 OCaml:2020年3月

欢迎阅读来自多核 OCaml 团队的 2020 年 3 月新闻更新!此更新由 @shakthimaan 和 @kayceesrk 共同整理,与2月1月的更新一样。

我们本月的重点工作是作为全面评估练习的一部分,对多核 OCaml 编译器和运行时进行性能改进。我们继续向 Sandmark 测试套件添加更多基准测试。事件日志跟踪系统和在 upstream OCaml 中使用哈希表进行编组正在进行中,并且更多 PR 也正在排队等待 OCaml 4.11.0-dev。

对于尝试使用该分支的用户来说,最大的可见变化是已合并了一个新的 GC(“并行次要 GC”),以取代之前的 GC(“并发次要 GC”)。我们将在稍后阶段详细介绍,但本质上是**并行次要 GC 不再需要读取屏障或更改 C API**。在非常多的核心数下,它的可扩展性特性可能略差,但在我们的评估中,最多 24 个核心时大致相当。鉴于无需移植现有的 C FFI 使用而带来的巨大可用性改进,我们已决定将并行次要 GC 作为我们第一个上游运行时补丁的默认 GC。当我们将测试扩展到 64 核及以上机器时,并发次要 GC 将在稍后阶段推出。对于那些希望在家中尝试它的人,多核 opam 远程已更新以反映这些更改。

我们现在正处于将大型应用程序移植到多核的阶段。感谢

  • @UnixJunkie 帮助我们在 https://github.com/ocaml-bench/sandmark/issues/99 中集成了 Gram Matrix 基准测试
  • @jhw 在 https://github.com/ocaml-multicore/ocaml-multicore/pull/240 中做了大量工作来支持 Systhreads。Systhreads 目前在多核中被禁用,导致一些流行的包无法编译。
  • @antron 一直在为我们提供有关如何最好地将 Lwt_preemptiveLwt_unix 模块移植到多核的建议,这为我们提供了一个广泛使用的 IO 堆栈,可以针对更多应用程序进行测试。

如果您还有其他建议的应用程序,您认为可以提供有用的基准测试,请与我或 @kayceesrk 联系。

进入细节!首先列出多核 OCaml 的各种正在进行和已完成的任务,然后是 Sandmark 基准测试基础设施的更改以及对上游 OCaml 的持续 PR。

多核 OCaml

正在进行

  • ocaml-multicore/ocaml-multicore#240 提议以 Domain 和 Atomic 为基础实现线程

    已经提出了 Threads 库的新实现(用于在多核 OCaml 中使用新的 DomainAtomic 模块)。这构建了 Dune 2.4.0,这反过来又使其能够构建其他包。此 PR 正在等待审查。

  • ocaml-multicore/safepoints-cmm-mach 更好的 OCaml 安全点

    在此分支中正在开发一种新的实现,以便在 Cmm 级别插入安全点。

已完成

以下 PR 已合并到多核 OCaml 中

  • ocaml-multicore/ocaml-multicore#303 正确计算增量标记预算

    该补丁正确测量了增量标记预算值,并提高了 menhir.ocamly 基准测试的最大延迟。

  • ocaml-multicore/ocaml-multicore#307 将阶段变化事件置于实际的阶段变化代码中。该 PR 在适当的上下文中包含了 major_gc/phase_change 事件。

  • ocaml-multicore/ocaml-multicore#309 不要一次获取所有完整的池。

    代码更改选择其中一个 global_full_pools 以尝试稍后对其进行扫描,而不是采用所有完整的池。

  • ocaml-multicore/ocaml-multicore#310 当前域的统计信息比其他域更新

    当前域的统计信息(minor_wordspromoted_wordsmajor_wordsminor_collections)更新,并在正确的上下文中使用。

  • ocaml-multicore/ocaml-multicore#315 caml_blit_fields 中的写入应始终使用 caml_modify_field 来记录 young_to_young 指针

    该 PR 强制始终使用 caml_modify_field() 来存储 young_to_young 指针。

  • ocaml-multicore/ocaml-multicore#316 修复 Weak.blit 的错误。

    短暂对象被分配为已标记,但是,键或数据可能未标记。blit 操作将弱引用从一个短暂对象复制到另一个短暂对象,而不会标记它们。该补丁标记了被 blit 的键,以便在另一个主要循环中保持不可到达的键存活。

  • ocaml-multicore/ocaml-multicore#317 对于长度为 0 的 blit,提前返回

    该 PR 在 byterun/weak.c 中,如果 blit 长度为零,则强制执行 CAMLreturn() 调用。

  • ocaml-multicore/ocaml-multicore#320 移动 num_domains_running 的递减

    需要在共享堆栈拆卸中使用 caml_domain_alone() 调用,因此 num_domains_running 的递减被移至至少 shared_heap 无锁快速路径的最后一个操作。

基准测试

Sandmark 性能基准测试套件添加了新的基准测试,并且正在努力增强其功能。

  • ocaml-bench/sandmark#88 添加 PingPong 多核基准测试

    现在已将使用生产者和消费者队列的 PingPong 基准测试包含到 Sandmark 中。

  • ocaml-bench/sandmark#98 添加读/写 Irmin 基准测试

    已将 Irmin 的基本读/写文件性能基准测试添加到 Sandmark 中。您可以更改以下输入参数:分支数、键数、读写百分比、迭代次数以及写操作数。

  • ocaml-bench/sandmark#100 添加 Gram Matrix 基准测试

    创建了一个请求 ocaml-bench/sandmark#99 以包含 Gram Matrix 初始化数值基准测试。这对于机器学习应用程序很有用,现在已在 Sandmark 性能基准测试套件中提供。多核(并发次要收集器)、Parmap 和 Parany 的加速比(sequential_time/multi_threaded_time)与核心数的关系非常显著,并在图表中进行了说明

Gram matrix speedup benchmark

  • ocaml-bench/sandmark#103 在 Makefile 中添加依赖目标

    Sandmark 现在包含在 Makefile 中定义的 depend 目标,以检查 libgmp-devlibdw-dev 包是否已安装并在 Ubuntu 上可用。

  • ocaml-bench/sandmark#90 更多并行基准测试

    已创建了一个问题以添加更多并行基准测试。我们将使用它来跟踪请求。请随时添加您希望使用的基准测试列表!

OCaml

正在进行

  • ocaml/ocaml#9082 事件日志跟踪系统

    配置脚本现已更新,以便它可以在 Windows 上构建。除了此主要更改之外,还为构建和健全性检查进行了一些次要提交。此 PR 目前正在审查中。

  • ocaml/ocaml#9353 使用哈希表重新实现 output_value 以检测共享。

    感谢 @xavierleroy,ocaml/ocaml#9293“使用 addrmap 哈希表进行编组”PR 已使用哈希表和位向量重新实现。这是使用并发垃圾收集器的多核 OCaml 的先决条件。

一如既往,我们感谢社区中的 OCaml 开发人员和用户对项目的代码审查、支持和贡献。来自 OCaml Labs,请在外面保持安全和健康!