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 更新,其中包含上游工作、改进、修复、测试套件和文档更改。接下来是 Eio
、Tezos
和 Domainslib
的生态系统更新。最后列出 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#795 将
Minor_heap_max
和Max_domains
设为OCAMLRUNPARAM
选项Minor_heap_max
在runtime/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_tag
和Cont_tag
都需要更新。 -
ocaml-multicore/ocaml-multicore#772 并非所有寄存器都需要为
caml_call_realloc_stack
保存C 被调用者保存的寄存器由
caml_try_realloc_stack
保存,并且它们不会调用 GC。无需在caml_call_realloc_stack
中保存所有寄存器。 -
ocaml-multicore/ocaml-multicore#775 在
gc_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/ocaml-multicore#794 审核
OCAMLRUNPARAM
选项一些
OCAMLRUNPARAM
选项(例如init_heap_wsz
和init_heap_chunk_sz
)可以删除,因为它们未使用。 -
ocaml-multicore/ocaml-multicore#796 域的
Caml_state
不应使用 mmapCaml_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#797
bigarray
上的原子访问一项实现
bigarray
原子访问的功能请求。 -
ocaml-multicore/ocaml-multicore#801
Sys.command
中的fork
调用关于在与
Sys.command
一起使用时是否需要保护fork
调用的查询。 -
ocaml-multicore/ocaml-multicore#810 使用多核和自定义块时出现段错误/未定义行为
@dannywillems (Danny Willems) 报告了 OCaml 中 Pippenger 基准测试实现的段错误和未定义行为。
-
ocaml-multicore/ocaml-multicore#816 使用过滤器树规范化提交者的电子邮件地址
需要使用过滤器树修复和合并多核 OCaml 中提交者之间不一致的名称和电子邮件地址。
已完成
上游
-
ocaml-multicore/ocaml-multicore#669 为域设置线程名称
现已合并实现多核 OCaml 线程命名的补丁,该补丁还提供了一个接口,用于以不同的方式命名域和线程。
-
ocaml-multicore/ocaml-multicore#701 Cherry pick:合并来自
ocaml-multicore/really_flush
的拉取请求 #701PR 更新了
stlib/format.ml
,以便在并行使用预定义格式化程序时刷新输出。 -
ocaml-multicore/ocaml-multicore#735 在
minor_gc.c
中添加caml_young_alloc_start
和caml_young_alloc_end
多核 OCaml 中不存在
caml_young_alloc_start
和caml_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_hook
、Thread.exit
和caml_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#763 将
Assert
移动到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#767 在
minor_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_actions
、caml_process_pending_actions
已将属于 C API 的
caml_check_pending_actions
和caml_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.h
、sys.h
、ui.h
、weak.h
、gc_ctrl.c
、gc.mli
和runtime/Makefile
中的 diff 噪音。它还从ocamldoc
和ocamltest
构建中删除了不必要的包含。 -
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-multicore/ocaml-multicore#779 重命名/隐藏一些全局变量
extern global
、pool_freelist
和atoms
的使用已分别替换为extern caml_heap_global_state
、static static_pool_freelist
和static 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.ml
中is_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.c
中memmove
的使用已替换为memcpy
,并且runtime/callback.c
和runtime/caml/callback.h
中的代码已清理。
修复
-
ocaml-multicore/ocaml-multicore#725 阻塞信号无限循环修复
添加了一个单调的
recorded_signals_counter
来修复当没有域可以处理阻塞信号时caml_enter_blocking_section
中可能出现的循环。目前的共识是从计数信号转向合并信号,因此这需要重写代码。 -
ocaml-multicore/ocaml-multicore#749
Forward_tag
短路上的潜在错误?在次要 GC 中,已禁用类型为
Forward_tag
、Lazy_tag
和Double_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
的 selectgeneffects_of
此 PR 将
Cdls_get
的effects_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#774 跳过不受支持和不兼容的测试
ocamltest
的内置操作skip
用于跳过不受支持和不兼容的测试。 -
ocaml-multicore/ocaml-multicore#784 恢复
testsuite/summarize.awk
testsuite/summarize.awk
已更新,使其更接近其ocaml/ocaml
版本。 -
ocaml-multicore/ocaml-multicore#786 以 OCaml 4.x 中的方式重新实现
caml_alloc_small
此 PR 重新引入了 OCaml 4.x 中
caml_alloc_small
的实现,因为它在sz
大于Max_young_wosize
时会进行断言。 -
ocaml-multicore/ocaml-multicore#798 将
asmgen
测试套件和 ocamltest 恢复为主干版本asmgen
和ocamltest
测试已更新,可以与ocaml/ocaml
正常构建。 -
ocaml-multicore/ocaml-multicore#808
signal_alloc
测试用例修复signal_alloc
测试用例已重新添加到测试套件中。 -
ocaml-multicore/ocaml-multicore#814 细微改进
已删除
asmcomp/reg.ml
中一个未使用的函数,并重新包含了一些禁用的测试。测试套件中的compare_programs
现在与主干版本匹配。
文档
-
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.mli
和runtime/caml/domain_state.tbl
中的注释已更新,提供了有关全局 GC 统计信息和每个域 GC 统计信息的信息。 -
ocaml-multicore/ocaml-multicore#802 更多关于域的注释
此 PR 在
domain.c
和domain.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-buffer
、new-cstruct
和chunk-as-cstruct
。复制 1GB 文件的结果在插图中显示。 -
ocaml-multicore/eio#120 添加
Fibre.fork_on_accept
和Net.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
关于将打开的对象作为每个函数的第一个参数,以及使用完整的单词和表达式而不是
network
、file_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.run
和Domain_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#109 在
eio_linux
工具中使用无锁运行队列lib_eio_linux/eio_linux.ml
文件已更新为使用无锁运行队列。下面显示了单核基准测试的结果。$ dune exec -- ./bench/bench_yield.exe`
-
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 中解释
Promises
和Streams
README 已更新,分别包含关于
Promises
和Streams
的部分,并且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
。在分叉时,调用者将在运行队列的头部进行调度,因为这种新的调度顺序更自然、更灵活,并且更适合缓存。 -
已添加
Fibre.check
函数以检查当前上下文是否已被取消,并更新了有关取消的文档。 -
ocaml-multicore/eio#121 添加生命周期结束和动态分派的理由
doc/rationale.md
中关于“指示文件结束”和“动态分派”的文档更新。
Tezos
-
ocaml-multicore/tezos-opam-repository#7 更新
来自上游的合并,其中包括对依赖包的更新以及向存储库添加新包。
-
ocaml-multicore/tezos-opam-repository#8 添加
domainslib.0.4.0
&lwt_domain.0.1.0
将
domainslib.0.4.0
和lwt_domain.0.1.0
添加到 tezos-opam-repository 中。 -
最新的上游构建、代码和文档更改已从 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+trunk
和4.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 显示多值数据点时显示最小值和最大值
现在在图表中显示了一系列提交的多值数据点的最小值和最大值。
-
ocurrent/current-bench#242 工作程序:每个 CPU 运行一个基准测试
您现在可以并行运行多个基准测试,每个基准测试使用自己的 CPU,在
.env
文件中使用以下设置OCAML_BENCH_DOCKER_CPU=4,5,6
-
ocurrent/current-bench#252 使 Debian 版本更明确
pipeline/Dockerfile
和pipeline/Dockerfile.env
文件已更新,以明确使用 Debian 镜像ocaml/opam:debian-11-ocaml-4.13
。 -
ocurrent/current-bench#254 允许为指标设置描述
current-bench 前端现在可以显示指标的描述,如下所示
-
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:工作组