OCaml 多核 - 2021 年 12 月和大型 PR

欢迎阅读 2021 年 12 月的 多核 OCaml 月度报告!此更新以及 之前的更新 由我本人、@ctk21、@kayceesrk 和 @shakthimaan 共同整理。

终于来了!@kayceesrk 向 OCaml 主要开发库提交了 多核 OCaml PR#10831,该 PR 代表了我们在 11 月核心团队审查 中决定的多核 OCaml 的“最小可行”实现。该分支包含大约 4000 次提交,突破了 GitHub 渲染能力的极限。

在圣诞节前不久提交 PR 后,剩下的工作就是让许多开发人员仔细检查 差异,并查找在多核开发过程中出现的任何意外更改。自从 PR 提交以来,大量代码更改、改进和修复已合并到 ocaml-multicore 树中,以促进此上游过程。我们预计将在 1 月份合并 PR,然后继续执行上个月描述的“MVP 后”任务,但从现在开始将直接从 ocaml/ocaml 中进行。因此,我们仍然有望在 2022 年发布 OCaml 5.00。

在多核生态系统中,进展也持续进行

  • Eio 作为推荐用于多核 OCaml 的基于效果的直接风格 IO 库,持续改进。
  • 发布了较新的 domainslib.0.4.0 版本,其中包含错误修复和 API 更改。
  • Sandmark 和 current-bench 之间进一步集成增强功能的持续基准测试管道正在取得进展。

我们还要感谢以下外部贡献者:

  • Danny Willems (@dannywillems),感谢他提供了 Pippenger 基准测试的 OCaml 实现并报告了一个未定义行为。
  • Matt Pallissard (@mattpallissard) 报告了使用供应商提供的 uring 时 Eio 的安装问题。
  • Edwin Torok (@edwintorok) 贡献了一个 domainslib 的 PR,以允许使用每个通道的键。

与往常一样,首先列出多核 OCaml 更新,其中包含上游工作、改进、修复、测试套件和文档更改。接下来是 EioTezosDomainslib 的生态系统更新。最后列出 Sandmark、sandmark-nightly 和 current-bench 任务,供您参考。

多核 OCaml

正在进行

上游

  • ocaml-multicore/ocaml-multicore#742 异步审查中的次要任务

    为 OCaml 5.00 版本提供了一个异步审查中的次要任务列表。主要任务将有各自的 GitHub 问题。

  • ocaml-multicore/ocaml-multicore#750 讨论多核下的 Lazy 设计

    关于多核 OCaml 下 Lazy 设计的持续讨论,涉及顺序 Lazy、并发问题、重复计算和内存安全。

  • ocaml-multicore/ocaml-multicore#756 RFC:将 Domain.DLS 接口泛化,以拆分子域的 PRNG 状态

    正在审查“正确”PRNG+Domains 语义的实现,其中生成域会“拆分”PRNG 状态。

  • ocaml-multicore/ocaml-multicore#791 缺少 caml_process_pending_actions_exn

    caml_process_pending_actions_exn 将异常作为 OCaml 值返回,而不是引发它们,并且在多核 OCaml 中缺少 C API 调用。

  • ocaml-multicore/ocaml-multicore#795Minor_heap_maxMax_domains 设为 OCAMLRUNPARAM 选项

    Minor_heap_maxruntime/caml/config.h 中定义为 2GB,Max_domains 定义为 128,在运行 AFL 和 Valgrind 等工具时,多核 OCaml 会出现内存不足问题。建议将这些参数设为 OCAMLRUNPARAM 选项。

  • ocaml-multicore/ocaml-multicore#799 使 CI 中的 runner.sh 与主干保持一致

    ocaml-multicore/ocaml-multicore 中的 runner.sh 脚本已更改,并与主干存在差异。需要更新它,使其与 ocaml/ocaml 保持同步。

  • ocaml-multicore/ocaml-multicore#806 统一 GC 中断和信号触发机制

    信号和 GC 中断之间的交互需要重新设计,因为它们存在于两个独立的机制中。

  • ocaml-multicore/ocaml-multicore#811 仔细检查通过 ocaml/ocaml 的变基

    正在审查 x86、ARM、PPC 和 s390x 架构的多核 OCaml 信号处理更改的移植。

  • 已从 ocaml/ocaml 创建了一个新的 ocaml-multicore/ocaml 项目库,以使其与主干保持同步。

改进

  • ocaml-multicore/ocaml-multicore#765 tools/gdb_ocamlrun.py 需要更新

    tools/gdb_ocamlrun.py 中包含硬编码的值,并且 Forcing_tagCont_tag 都需要更新。

  • ocaml-multicore/ocaml-multicore#772 并非所有寄存器都需要为 caml_call_realloc_stack 保存

    C 被调用者保存的寄存器由 caml_try_realloc_stack 保存,并且它们不会调用 GC。无需在 caml_call_realloc_stack 中保存所有寄存器。

  • ocaml-multicore/ocaml-multicore#775gc_regs_bucket 中使用显式 next 指针

    amd64.S 中,gc_regs_bucket 的最后一个字包含 rax 的保存值或指向先前结构的指针。建议为这两个实体使用不同的成员。

  • ocaml-multicore/ocaml-multicore#793 基于环形缓冲区的运行时跟踪 (eventring)

    Eventring 是一个用于持续监控 OCaml 应用程序的低开销运行时跟踪系统。它是运行时中现有事件日志系统的替代方案,并使用每个域的内存映射环形缓冲区。下面显示了在 Chrome 的跟踪查看器上运行 OCAML_EVENTRING_START=1 _build/default/src/traceevents_lib.exe 生成的 JSON 输出

    OCaml-Multicore-PR-793-Chrome|690x149

  • ocaml-multicore/ocaml-multicore#794 审核 OCAMLRUNPARAM 选项

    一些 OCAMLRUNPARAM 选项(例如 init_heap_wszinit_heap_chunk_sz)可以删除,因为它们未使用。

  • ocaml-multicore/ocaml-multicore#796 域的 Caml_state 不应使用 mmap

    Caml_state 不再位于次要堆区域的相邻位置,次要堆区域的分配使用 mmap 完成。目前,使用专用寄存器(amd64 上的 r14)指向 Caml_state。在域创建时使用 malloc 足以简化和管理 Caml_state

  • ocaml-multicore/ocaml-multicore#805 改善 stack_size_bucket/alloc_stack_noexc

    stack_size_bucket/alloc_stack_noexc 不是 2 的幂时,当前的堆栈缓存方案将不会使用缓存。新堆栈从 caml_fiber_wsz 开始,并以 2 的倍数递增。此代码有改进和重构的空间。

其他事项

已完成

上游

  • ocaml-multicore/ocaml-multicore#669 为域设置线程名称

    现已合并实现多核 OCaml 线程命名的补丁,该补丁还提供了一个接口,用于以不同的方式命名域和线程。

  • ocaml-multicore/ocaml-multicore#701 Cherry pick:合并来自 ocaml-multicore/really_flush 的拉取请求 #701

    PR 更新了 stlib/format.ml,以便在并行使用预定义格式化程序时刷新输出。

  • ocaml-multicore/ocaml-multicore#735minor_gc.c 中添加 caml_young_alloc_startcaml_young_alloc_end

    多核 OCaml 中不存在 caml_young_alloc_startcaml_young_alloc_end,现在已将其包含为兼容性宏。

  • ocaml-multicore/ocaml-multicore#737 将新的 ephemeron API 移植到 5.00

    已在主干中 合并 了不可变 ephemerons 的 API,并且已将相应的更改移植到 5.00。

  • ocaml-multicore/ocaml-multicore#740 Systhread 生命周期

    已合并 caml_thread_domain_stop_hookThread.exitcaml_c_thread_unregister 中的修复程序。PR 还解决了多核 OCaml 中的 systhread 生命周期。

  • ocaml-multicore/ocaml-multicore#745 Systhreads WG3 评论

    此 PR 更新了提交信息使其更具描述性,使用了非原子变量,并在分配线程描述符失败时引发 OOM 错误。

  • ocaml-multicore/ocaml-multicore#748 WG3 移动 gen_sizeclasses

    runtime/gen_sizeclasses.ml 已移动到 tools/gen_sizeclasses.ml,并且已修复并合并了拼写错误检查问题。

  • ocaml-multicore/ocaml-multicore#762 删除裸指针检查器

    此 PR 删除了裸指针检查器,因为它在 Multicore OCaml 中不受支持。

  • ocaml-multicore/ocaml-multicore#763Assert 移动到 CAMLassert

    Assert 已替换为 CAMLassert,并且已修复许可证文件和行长度的拼写错误检查更改并已合并。

  • ocaml-multicore/ocaml-multicore#764 处理 shared_heap.c 代码审查 (WG1)

    runtime/shared_heap.c 代码已更新,使用 NULL 而不是 0 初始化变量。

  • ocaml-multicore/ocaml-multicore#766 来自同步审查和 WG3 的信号更改

    在生成域之前会阻塞信号,并在之后安全时解除阻塞。total_signals_pending 已删除,我们现在通过信号编号合并信号。

  • ocaml-multicore/ocaml-multicore#767minor_gc 头部读取中将 relaxed 更改为 acquire

    memory_order_relaxed 现在在 runtime/minor_gc.c 中替换为 memory_order_acquire(适用于 5.00 版本)。

  • ocaml-multicore/ocaml-multicore#768 使 intern 不调用 GC

    此 PR 使 intern 的实现更接近主干 OCaml,并且 intern 不再触发 GC。下面列出了在一个简单的二叉树基准测试上的性能结果。

    N    OCaml trunk 	 This PR    Slowdown
    2    1.20E-07      1.20E-07   0.00%
    4    3.10E-07      3.20E-07   3.23%
    8    9.10E-06      1.40E-05   53.85%
    16   2.60E-03      3.90E-03   50.00%
    20   4.60E-02      6.40E-02   39.13%
    22   2.20E-01      2.70E-01   22.73%
    24   1.10E+00      1.20E+00   9.09%
    25   1.90E+00      2.10E+00   10.53%
    
  • ocaml-multicore/ocaml-multicore#770 PR770 的反向移植

    otherlibs/systhreads/st_stubs.c 文件已格式化以清除卫生检查,并且已对 backtrace_last_exn 进行更改以使其更接近主干。

  • ocaml-multicore/ocaml-multicore#771 使 systhreads 中 backtrace_last_exn 的根管理更接近主干

    systhreads 中 backtrace_last_exn 的根管理已更新,使其更接近 ocaml/ocaml

  • ocaml-multicore/ocaml-multicore#773 基于异步审查的改进

    现在在使用之前分配 extern 状态,并且已对 amd64.S 进行了改进。

  • ocaml-multicore/ocaml-multicore#781 适用于 4.12 域的 PR771

    这是 PR#771 针对 4.12+domains 分支的反向移植。

  • ocaml-multicore/ocaml-multicore#789 审查改进

    主干的文本段命名风格已更新为 runtime/amd64.S,并对 runtime/fiber.c 进行了改进。此外,还删除了 runtime/interp.c 中不必要的重置。

  • ocaml-multicore/ocaml-multicore#790 添加 ocaml_check_pending_actionscaml_process_pending_actions

    已将属于 C API 的 caml_check_pending_actionscaml_process_pending_actions 添加到 OCaml Multicore 中。

  • ocaml-multicore/ocaml-multicore#813 恢复 arm64 更改和 ocaml-variant.opam 文件

    asmcomp/arm64/* 文件和 ocaml-variants.opam 文件已更新,使其更接近主干。

  • ocaml-multicore/ocaml-multicore#815 各种调整

    此 PR 减少了 major_gc.hsys.hui.hweak.hgc_ctrl.cgc.mliruntime/Makefile 中的 diff 噪音。它还从 ocamldococamltest 构建中删除了不必要的包含。

  • ocaml-multicore/ocaml-multicore#818 来自审查的细微修复

    此 PR 更新了 otherlibs/systhreads/st_stubs.c 中的注释,在 runtime/caml/sync.h 中使用 memcpy 代替 memmove,并在 asmcomp 源文件中进行了一些细微修复。

  • ocaml-multicore/ocaml-multicore#819 不要在 caml_alloc_shr 中初始化

    array.c 源文件已更新,使用非初始化分配以匹配主干。

  • ocaml/ocaml#10831 Multicore OCaml

    这是将 Multicore OCaml 合并到 ocaml/ocaml 的 PR,支持通过域进行共享内存并行处理,以及通过效果处理器进行并发处理。它在语言特性、C API 和单线程代码的性能方面与之前版本兼容。下面显示了在配备 64 核的双处理器 AMD EPYC 7551 服务器上,来自 Sandmark 的并行基准测试的扩展性结果。

    OCaml-PR-10831-Speedup|674x500

改进

  • ocaml-multicore/ocaml-multicore#779 重命名/隐藏一些全局变量

    extern globalpool_freelistatoms 的使用已分别替换为 extern caml_heap_global_statestatic static_pool_freeliststatic atoms

  • ocaml-multicore/ocaml-multicore#785 不导出一些没有前缀的全局名称

    现在将没有 caml_ 前缀的全局变量设置为静态。下面显示了更改前后的输出。

    之前

    $ readelf -s ./runtime/libcamlrun_shared.so  | grep GLOBAL | egrep -v ' UND | caml_'
     198: 00000000000562a0    40 OBJECT  GLOBAL DEFAULT   26 signal_install_mutex
     549: 0000000000000038     8 TLS     GLOBAL DEFAULT   18 Caml_state
     559: 0000000000056680     8 OBJECT  GLOBAL DEFAULT   26 marshal_flags
     622: 000000000001bf10   178 FUNC    GLOBAL DEFAULT   12 ephe_sweep
     642: 00000000000707e0     8 OBJECT  GLOBAL DEFAULT   26 garbage_head
     665: 000000000001bb80   729 FUNC    GLOBAL DEFAULT   12 ephe_mark
     783: 000000000001dfe0   229 FUNC    GLOBAL DEFAULT   12 reset_minor_tables
    1003: 0000000000052b20    24 OBJECT  GLOBAL DEFAULT   26 ephe_cycle_info
    1025: 00000000000165d0    19 FUNC    GLOBAL DEFAULT   12 main
    1042: 00000000000383e0    87 FUNC    GLOBAL DEFAULT   12 verify_push
     323: 0000000000051000     0 OBJECT  LOCAL  DEFAULT   24 _GLOBAL_OFFSET_TABLE_
     454: 0000000000052b20    24 OBJECT  GLOBAL DEFAULT   26 ephe_cycle_info
     564: 00000000000383e0    87 FUNC    GLOBAL DEFAULT   12 verify_push
     577: 00000000000562a0    40 OBJECT  GLOBAL DEFAULT   26 signal_install_mutex
     637: 00000000000707e0     8 OBJECT  GLOBAL DEFAULT   26 garbage_head
     831: 0000000000000038     8 TLS     GLOBAL DEFAULT   18 Caml_state
     910: 0000000000056680     8 OBJECT  GLOBAL DEFAULT   26 marshal_flags
    1092: 00000000000165d0    19 FUNC    GLOBAL DEFAULT   12 main
    1338: 000000000001bf10   178 FUNC    GLOBAL DEFAULT   12 ephe_sweep
    1424: 000000000001bb80   729 FUNC    GLOBAL DEFAULT   12 ephe_mark
    1437: 000000000001dfe0   229 FUNC    GLOBAL DEFAULT   12 reset_minor_tables
    

    之后

    $ readelf -s ./runtime/libcamlrun_shared.so  | grep GLOBAL | egrep -v ' UND | caml_'
     548: 0000000000000038     8 TLS     GLOBAL DEFAULT   18 Caml_state
    1018: 00000000000165a0    19 FUNC    GLOBAL DEFAULT   12 main
     329: 0000000000051000     0 OBJECT  LOCAL  DEFAULT   24 _GLOBAL_OFFSET_TABLE_
     833: 0000000000000038     8 TLS     GLOBAL DEFAULT   18 Caml_state
    1093: 00000000000165a0    19 FUNC    GLOBAL DEFAULT   12 main
    
  • ocaml-multicore/ocaml-multicore#792 Stdlib:简化 is_main_domain

    stdlib/domain.mlis_main_domain 的实现变得更简单,并且此 PR 还删除了 caml_ml_domain_is_main_domain 原语。

  • ocaml-multicore/ocaml-multicore#803 删除调试运行时与堆栈调整大小的差异

    已删除标准运行时和调试运行时之间堆栈调整大小的差异,以便帮助使用调试运行时中相同的堆栈调整大小来重现标准运行时中遇到的任何错误。

  • ocaml-multicore/ocaml-multicore#804 删除冗余的打开

    已删除 testsuite/tests/weak-ephe-final/ephetest_par.ml 中冗余的 open 调用。

  • ocaml-multicore/ocaml-multicore#820 细微改进

    runtime/sys.cmemmove 的使用已替换为 memcpy,并且 runtime/callback.cruntime/caml/callback.h 中的代码已清理。

修复

  • ocaml-multicore/ocaml-multicore#725 阻塞信号无限循环修复

    添加了一个单调的 recorded_signals_counter 来修复当没有域可以处理阻塞信号时 caml_enter_blocking_section 中可能出现的循环。目前的共识是从计数信号转向合并信号,因此这需要重写代码。

  • ocaml-multicore/ocaml-multicore#749 Forward_tag 短路上的潜在错误?

    在次要 GC 中,已禁用类型为 Forward_tagLazy_tagDouble_tag 的值的短路,并且已修复在类型为 Obj.forcing_tag 的值上对 Forward_tag 进行短路时发生的错误。

  • ocaml-multicore/ocaml-multicore#760 简化延迟语义

    已删除 RacyLazy 异常。domain-local id 和 try_force 也已被删除。任何并发使用延迟值的代码都可能引发未定义的异常。

  • ocaml-multicore/ocaml-multicore#761 amd64.S 中的错误修复和常规清理

    runtime/amd64.S 中的 jl(如果带符号小于则跳转)已更改为 jb(如果无符号小于则跳转),并且 asmcomp/amd64/emit.mlp 中的代码已清理。

  • ocaml-multicore/ocaml-multicore#769 移动帧描述符头文件并修复拼写错误

    来自 runtime 的帧描述符头文件已移动到 runtime/caml 并使用 CAML_INTERNALS 进行条件编译。如果代码在没有 -g 的情况下编译,则已添加额外的 NULL 检查。

  • ocaml-multicore/ocaml-multicore#788 修复 Cdls_Get 的 selectgen effects_of

    此 PR 将 Cdls_geteffects_of 移动到 asmcomp/selectgen.ml 中的 EC.coeffect_only Coffect.Read_mutable

  • ocaml-multicore/ocaml-multicore#809 完成存储库中的 tools/check-typo

    已删除 runtime/caml/stack.h 中的 Callback_link,并且此 PR 清理了 tools/check-typo 报告的修复。

测试

文档

  • ocaml-multicore/ocaml-multicore#752 记录当前 Multicore 测试套件的情况

    Multicore 测试套件现在与 ocaml/ocaml 的运行方式相同,因此此问题已关闭。

  • ocaml-multicore/ocaml-multicore#759 重命名类型变量以提高清晰度

    已合并更新 stdlib/fiber.ml 中类型变量以保持一致性和清晰度的 PR。

  • ocaml-multicore/ocaml-multicore#778 关于 caml_domain_spawn 也调用 install_backup_thread 的注释

    一条注释,说明域 0 首次生成域时,以及备份线程未激活并随后启动时的场景。

  • ocaml-multicore/ocaml-multicore#787 处理异步审查中关于 GC 的反馈

    runtime/finalise.c 中为 coaml_final_merge_finalisable 添加了一条注释,解释了为什么将源的年轻代添加到目标的旧代。计算出的上限工作限制设置为 0.3,因为在一个片段中无法执行超过 GC 周期的 1/3。

  • ocaml-multicore/ocaml-multicore#800 文档说明哪些 GC 统计信息是全局的,哪些是每个域的

    stdlib/gc.mliruntime/caml/domain_state.tbl 中的注释已更新,提供了有关全局 GC 统计信息和每个域 GC 统计信息的信息。

  • ocaml-multicore/ocaml-multicore#802 更多关于域的注释

    此 PR 在 domain.cdomain.ml 中添加了注释,其中包含停止世界部分的高级设计、备份线程的状态机、带互斥锁的信号处理(用于 Domain.join)以及停止世界参与者集的锁定机制。

其他

  • ocaml-multicore/ocaml-multicore#776 仅允许域 0 使用 Dynlink

    仅主域允许使用 Dynlink,并且公共函数的入口点需要进行相同的检查。

  • ocaml-multicore/ocaml-multicore#807 确保在 create_domain 期间未显式初始化的变量都已初始化

    此 PR 在 `runtime/domain.c` 中添加了变量初始化,在 `create_domain` 或任何使用的子函数中进行初始化。

  • ocaml-multicore/ocaml-multicore#817 使 opam 文件与 ocaml-options 包同步。

    ocaml-variants.opam 文件已更新为使用 ocaml-options 包,以与 opam-repository 的变体和当前 Multicore 存储库中的方案同步。

生态系统

正在进行

  • ocaml-multicore/multicore-opam#61 删除 omake

    caml_modify_field 在主干中不存在。此 PR 删除了 omake,因为它仅在 +effects 中需要。

  • ocaml-multicore/multicore-opam#62 删除 domainslib

    Domainslib.0.3.0 已经上游到 opam-repository,因此已从该存储库中删除。

  • ocaml-multicore/eio#116 对各种复制系统进行基准测试

    关于对三种技术的复制数据到缓冲区的基准测试和优化进行了公开讨论:fixed-buffernew-cstructchunk-as-cstruct。复制 1GB 文件的结果在插图中显示。

    Eio-PR-116-Copy-screenshot|357x499

  • ocaml-multicore/eio#120 添加 Fibre.fork_on_acceptNet.accept

    此 PR 中,fork_on_accept 现在在一个新的 switch 中使用 accept 函数,并将成功的结果传递给新 fibre 中的处理程序函数。Net.accept 函数处理可以接受单个连接的情况。

已完成

Eio

  • ocaml-multicore/eio#87 由于供应商冲突,Eio 无法安装

    将 uring 标记为供应商会破坏安装 修复程序解决了此问题。Matt Pallissard (@mattpallissard) 报告了此问题。

  • ocaml-multicore/eio#91 [讨论] 对象能力/API

    关于将打开的对象作为每个函数的第一个参数,以及使用完整的单词和表达式而不是 networkfile_systems 等的讨论现已结束,并更新了 eio#90

  • ocaml-multicore/eio#101 使 luv 后端线程安全

    lib_eio_luv/eio_luv.ml 的更新,使 luv 后端线程安全,并防止基准测试执行中的死锁。

  • ocaml-multicore/eio#102 对 luv 后端使用无锁运行队列

    此 PR 消除了围绕队列使用互斥量的需要,并且在单域基准测试中有一个微不足道的改进。

    之前

    $ make bench EIO_BACKEND=luv
    dune exec -- ./bench/bench_yield.exe
    n_fibers, ns/iter, promoted/iter
           1,   95.00,        0.0026
           2,  151.19,       12.8926
           3,  151.80,       12.8930
           4,  147.99,       12.8934
           5,  148.09,       12.8938
          10,  147.75,       12.8960
          20,  149.30,       12.9003
          30,  151.43,       12.9047
          40,  153.97,       12.9088
          50,  155.53,       12.9131
         100,  158.35,       12.9344
         500,  173.89,       13.0800
        1000,  182.50,       13.1779
       10000,  168.52,       13.7133
    

    之后

    $ make bench EIO_BACKEND=luv
    dune exec -- ./bench/bench_yield.exe
    n_fibers, ns/iter, promoted/iter
           1,   93.94,        4.9996
           2,   93.13,        5.0021
           3,   92.17,        5.0046
           4,   92.21,        5.0071
           5,   91.45,        5.0090
          10,  114.29,        5.0194
          20,   96.17,        5.0468
          30,   97.83,        5.0677
          40,   98.82,        5.0959
          50,   99.70,        5.1197
         100,  107.31,        5.2409
         500,  132.94,        6.1383
        1000,  142.85,        6.6771
       10000,  114.80,        5.9410
    
  • ocaml-multicore/eio#103 添加 Domain_manager.run 以使用事件循环启动域

    lib_eio/eio.ml 代码添加了 Domain_manager.runDomain_manager.run_raw 函数。Domain_manager.run 函数只能访问来自调用域的线程安全值。

  • ocaml-multicore/eio#104 分离 Ctf_unix 模块

    已从 Eio 模块中删除了对 Unix 的依赖关系,并添加了 Ctf_unix.with_tracing 函数以方便使用。

  • ocaml-multicore/eio#106 避免在 Eio_linux.run 中使用 Fun.protect

    已从 lib_eio_linux/eio_linux.ml 中删除了 Fun.protect 的使用,因为它会抛出一个异常,这在调度程序崩溃时没有用。

  • ocaml-multicore/eio#107 使取消线程安全

    取消上下文现在有一个 fibre 列表,当一个 fibre 分叉时,它会被添加到列表中。一旦 fibre 完成,它就会从列表中删除。该列表只能从 fibre 自身所在的域访问,并且每个 fibre 持有一个单一的、可选的原子取消函数。

  • ocaml-multicore/eio#108 清理 Waiters API

    许多用户不需要结果类型,因此已将其删除。相关的文档也已更新。

  • ocaml-multicore/eio#109eio_linux 工具中使用无锁运行队列

    lib_eio_linux/eio_linux.ml 文件已更新为使用无锁运行队列。下面显示了单核基准测试的结果。

    $ dune exec -- ./bench/bench_yield.exe`
    

    Eio-PR-109-Before-After|690x429

  • ocaml-multicore/eio#110 使 Waiters.wake_one 在取消时安全

    由于在取消等待者后调用了 wake_one,因此在使用多个域时我们无法唤醒任何内容。此 PR 在 lib_eio/waiters.ml 中修复了此问题,并添加了一个压力测试。

  • ocaml-multicore/eio#111 恢复域测试

    tests/tests_domains.md 文件现已启用,因为 Multicore OCaml 的修复程序已回移植到 4.12+domains。测试现在也将在 CI 中运行。

  • ocaml-multicore/eio#112 添加 Stream.take_nonblocking

    lib_eio/stream.ml 文件已更新为包含 Stream.take_nonblocking 函数以及一些测试。

  • ocaml-multicore/eio#113 在 README 中解释 PromisesStreams

    README 已更新,分别包含关于 PromisesStreams 的部分,并且 Fibre.fork 代码和测试已简化。

  • ocaml-multicore/eio#114 允许取消 Domain_mgr.run

    lib_eio/eio.ml 中的 run() 函数已更新为将取消异常注入到生成的域中。已将取消另一个域和在已取消时生成的测试添加到 tests/test_domains.md 中。

  • ocaml-multicore/eio#115 在分叉之前创建 fibre 上下文

    创建了一个 fibre 但没有立即启动它,这允许在调度方面有更大的灵活性并减少上下文数量。

  • ocaml-multicore/eio#117 允许设置 SO_REUSEPORT 选项

    此 PR 添加了对 linux_uring 后端设置 SO_REUSEPORT 套接字的支持。

  • ocaml-multicore/eio#118 改善分叉的调度

    旧的 Fork 效应已类似于 Fork_ignore 实现,并且 Fork_ignore 已重命名为 Fork。旧的 Fiber.fork 现在是 Fibre.fork_promise。在分叉时,调用者将在运行队列的头部进行调度,因为这种新的调度顺序更自然、更灵活,并且更适合缓存。

  • ocaml-multicore/eio#119 改进取消

    已添加 Fibre.check 函数以检查当前上下文是否已被取消,并更新了有关取消的文档。

  • ocaml-multicore/eio#121 添加生命周期结束和动态分派的理由

    doc/rationale.md 中关于“指示文件结束”和“动态分派”的文档更新。

Tezos

Domainslib

  • ocaml-multicore/domainslib#50 Multi_channel:允许每个程序使用不同配置的多实例

    Multi_channel 中存在一个共享全局状态,形式为 dls_new_key,会导致数组越界索引。此 PR 由 Edwin Torok (@edwintorok) 贡献,删除了全局键,并使用每个通道的键。

  • ocaml-multicore/domainslib#60 parallel_scan 中的错误修复

    对于 ~num_additional_domains:1 以及拒绝输入数组大小小于池大小的情况,数组结果中的最后一个条目不正确。

  • 已发布新的 domainslib.0.4.0,其中包含一个重大更改。我们现在需要对任务创建使用效果处理程序,并且所有计算都需要包含在 Task.run 函数中。

基准测试

Sandmark 和 Sandmark-nightly

正在进行

  • ocaml-bench/sandmark-nightly#23 Sandmark nightly 问题

    sandmark.ocamllabs.io 服务上观察到的问题列表,这些问题来自 Navajo 和 Turing 机器返回的结果。

  • ocaml-bench/sandmark-nightly#24 从 ocurrent-deployer 使用 git clone

    Dockerfile 的更新,使用 ocurrent-deployer 中的 git clone,而不是 ocaml-bench/sandmark-nightly

  • ocaml-bench/sandmark#266 为 OCaml 5.00.0+trun 和 4.14.0+domains 运行暂停时间

    在主干冻结后,需要更新 Sandmark 中的暂停时间变体,以便为 5.00.0+trunk4.14.0+domains 添加运行暂停时间。

  • ocaml-bench/sandmark#268 将 README CI 构建状态更新到主分支

    Sandmark 中 main 分支的 CI 构建状态 需要指向 main 分支而不是 master 分支。

已完成

  • ocaml-bench/sandmark#264 4.12 的清理

    已从 Sandmark 中删除 4.12.* 变体,并且脚本和文档已更新以反映这一点。

  • ocaml-bench/sandmark#265 添加包删除功能和 5.00 的构建

    main 分支现在支持 OCaml 变体的 package remove 选项,您可以动态取消选择不希望构建的依赖项包。例如,在 ocaml-versions/5.00.0+trunk.json 中,您可以指定以下内容

    {
       "url" : "https://github.com/ocaml/ocaml/archive/trunk.tar.gz",
       "package_remove": [
         "index",
         "integers",
         "irmin",
         "irmin-layers",
         "irmin-pack",
         "js_of_ocaml-compiler",
         "ppx_derivers",
         "ppx_deriving",
         "ppx_deriving_yojson",
         "ppx_irmin",
         "ppx_repr",
         "stdio"
       ]
    }
    

    此 PR 还引入了 Sandmark master 分支的最新更改,并成功为 .drone.yml CI 构建了 5.00.0+trunk。

  • ocaml-bench/sandmark#267 添加了对 bench.Dockerfile 的支持

    Sandmark 中已包含 bench.Dockerfile 用于使用 current-bench 项目构建和运行基准测试。

current-bench

正在进行

  • ocaml-multicore-ci#15 在 README 中添加依赖项安装步骤

    在为本地存储库安装和运行 ocaml-multicore-ci 之前,需要执行以下命令

    $ opam update
    $ opam install -t .
    
  • ocurrent/ocluster#151 公共 Ocluster_worker

    此 PR 公开了内部库 Ocluster_worker 供 current-bench 和 Sandmark 使用,因为我们需要一个具有自定义设置的特定工作程序来确保基准测试的稳定性。

  • ocurrent/ocluster#154 使用 opam update,删除 --verbose--connect 选项

    README 文档更新,包含使用 ocluster 可用的最新说明和选项。

  • ocurrent/current-bench#226 仅构建其依赖项在 CI 中构建良好的基准测试

    CI/CB 管道可以集成和扩展,以允许构建在 CI 中已知可以为各种 OCaml 变体干净构建的基准测试中的那些依赖项。

  • ocurrent/ocaml-ci#399 在 README 中添加依赖项安装步骤

    ocaml-ci 项目可以针对本地项目目录运行,并且已将更新和安装所需依赖项的 opam 命令添加到 README 中。

已完成

  • ocurrent/current-bench#216 添加自定义 OCluster 工作程序以构建和运行基准测试

    此 PR 提供了一个 OCluster 工作程序,使我们能够从主管道构建和运行基准测试,并修复了 Multicore 存储库设置。

  • ocurrent/current-bench#241 显示多值数据点时显示最小值和最大值

    现在在图表中显示了一系列提交的多值数据点的最小值和最大值。

    Current-bench-241-Min-Max|690x388

  • ocurrent/current-bench#242 工作程序:每个 CPU 运行一个基准测试

    您现在可以并行运行多个基准测试,每个基准测试使用自己的 CPU,在 .env 文件中使用以下设置

    OCAML_BENCH_DOCKER_CPU=4,5,6
    
  • ocurrent/current-bench#252 使 Debian 版本更明确

    pipeline/Dockerfilepipeline/Dockerfile.env 文件已更新,以明确使用 Debian 镜像 ocaml/opam:debian-11-ocaml-4.13

  • ocurrent/current-bench#254 允许为指标设置描述

    current-bench 前端现在可以显示指标的描述,如下所示

    Current-bench-254-Metrics-Description|690x216

  • ocurrent/current-bench#257 配置存储库以使用特定工作程序和 OCaml 版本运行

    可以为 current-bench 提供静态配置,指定要与基准测试一起使用的哪些工作程序和 OCaml 版本。这对于获取启用多核的 Sandmark 工作程序的确定性结果很有用。例如

    [
      {
        "name": "author/repo",
        "worker": "autumn",
        "image": "ocaml/opam"
      },
      {
        "name": "local/local",
        "image": "ocaml/opam:debian-ocaml-4.11"
      }
    ]
    

我们特别感谢社区中所有 OCaml 用户、开发人员和贡献者为项目投入的宝贵时间和持续支持。祝大家平安,新年快乐!

缩略词

  • AFL:American Fuzzy Lop
  • AMD:超微半导体公司
  • API:应用程序编程接口
  • ARM:高级精简指令集机器
  • CI:持续集成
  • CPU:中央处理器
  • DLS:域本地存储
  • EPYC:极致性能收益计算
  • GC:垃圾回收器
  • GDB:GNU 项目调试器
  • IO:输入/输出
  • JSON:JavaScript 对象表示法
  • MD:Markdown
  • MLP:ML 文件预处理
  • OOM:内存溢出
  • OPAM:OCaml 包管理器
  • PPC:增强型精简指令集性能优化 - 性能计算(PowerPC)
  • PR:拉取请求
  • PRNG:伪随机数生成器
  • RFC:征求意见稿
  • STW:停止世界
  • WG:工作组