单机并行

说明路径搜索、切片任务分块和矩阵乘法的并行方式,以及线程数与实际 CPU 使用量的区别。

本页目录

一次调用中的并行搜索

Light / Heavy 的编译库接收调用方的 Rayon 线程池宽度,并在一次调用内安排并行搜索。无需在调用外再写种子循环;seed 指定本次搜索的基础种子。使用 Heavy给出单次调用示例。

例如 RAYON_NUM_THREADS=8 设置 8 个工作线程。它不预留 8 个物理核,也不固定进程 affinity;实际 CPU 使用量由可并行任务、系统调度和其他负载共同决定。内部起点数与候选调度不是公开返回字段。

Light 和 Heavy 建议从 8 个工作线程开始。需要增加搜索投入且有足够 CPU 资源时,可使用 16、24 或 32 个线程。当前实现按每 8 个线程增加一个独立搜索起点:

RAYON_NUM_THREADS 独立搜索起点数
8 1
16 2
24 3
32 4

各起点使用不同种子,由一次调用并行调度,最后按本次优化目标选择结果。它们共享总线程池,不是顺序执行两轮或三轮,也不为每个起点固定绑定 8 个核心。基础种子通过 seed 指定,其余种子由库派生。

在程序启动前设置线程数。例如,有 24 个可用物理核心时,可设置:

bash
RAYON_NUM_THREADS=24 python plan.py

8 是建议的起始配置,不是强制的最小值,也不是对所有网络都最快的配置。未显式设置线程数时,由 Rayon 运行时决定,不固定为 8。更多起点增加搜索工作量,可能改善路径质量,不表示单次搜索按比例加速。

并行单位

位置 可并行工作 仍需顺序或同步的部分
Light / Heavy 多个独立起点及每个起点内的搜索任务 搜索过程中的依赖与结果汇总
random_greedy 多次完整搜索 单次搜索中的贪心步骤
bisect 多次独立划分 一次递归划分的父子调用
order_dp 长度相同的不同区间 区间长度从小到大推进
anneal_paths / treesa_path 多条独立搜索链 单条链内的局部旋转
temper_path(s) 同一轮中各副本的局部搜索 轮末相邻副本交换,以及下一轮的开始
原生切片执行 多组切片任务 每组内部的求和顺序,以及各组部分和的合并顺序
matrixmultiply mt 单个 GEMM 内部线程 由可选 Cargo feature 和线程上限控制

对公开低层算法,并行对象的数量给出阶段并行度上限;给一个阶段更多线程,不代表它能持续占用同样数量的 CPU 核。单独调用低层算法时,不会额外采用 Light 和 Heavy 的独立起点调度规则。

线程池与嵌套并行

bash
RAYON_NUM_THREADS=8 cargo run --release --bin tnpath -- \
  network.json --method auto --preset heavy --seed 0

RAYON_NUM_THREADS=8 MATMUL_NUM_THREADS=1 tnexec \
  --net network.json --load-path plan.json
控制项 作用域
RAYON_NUM_THREADS Light / Heavy 路径搜索、公开低层算法和原生切片任务分块
MATMUL_NUM_THREADS 启用 matrixmultiply mt feature 时的单个 GEMM 内线程
CPU affinity / launcher binding 进程实际可以运行在哪些 CPU 上

外层 Rayon 与内层 GEMM 同时使用多线程,可能使可运行线程数超过可用 CPU 数量,产生过量订阅(oversubscription)。tnexec 在外层切片分块多于 1、且调用者未设置 MATMUL_NUM_THREADS 时,将它设为 1;已有设置不会被覆盖。默认 Python wheel 不启用 matrixmultiply 的可选线程池。

线程数、工作量和结果

对低层固定 ntrials、chains、rounds 或 moves 的调用,增加线程主要改变完成这些工作所需的实际时间。Light 和 Heavy 的搜索工作量可能随线程设置变化,因此比较不同线程数时,应同时记录实际耗时与路径质量,不能直接视为固定工作量的线程加速。

比较问题 需要固定的量
固定工作量的线程加速 同一入口、trial/chain/round 数、seed、objective 和输出验证
不同资源配置下的 Light / Heavy 结果 记录配置、实际耗时和最终路径指标;工作量不同时,不能作为固定工作量的强缩放测试
设置 max_time 后的结果 外部总时间上限、重复次数和实际完成工作量;检查点触发时间会受运行时序影响
切片执行加速 同一 path、sliced legs、dtype、chunk 规则和后端

线程池宽度不是物理核数,也不是实际平均用核。只写 RAYON_NUM_THREADS=8 不能证明阶段使用了 8 个物理核。

并行运行时需要记录的信息

阶段平均 CPU 使用量可以用 process CPU time / wall time 估计。例如比值为 2 表示该窗口内平均每秒消耗 2 个 CPU 秒,不能单独证明使用了多少物理核。等待、内存带宽瓶颈或任务不足都会使该比值低于线程池宽度。