Skip to content

算法Algorithm

并行前缀扫描

施工中 · 内容逐步修订

parallel prefix scan · parallel scan · prefix computation

用上扫归约和下扫传播在线性工作、对数深度内计算任意幺半群运算的全部前缀。

形式陈述 ​

接口与代数前提 ​

给定幺半群 (M,⊗,e) 与长度 n≥1 的序列 a0,…,an−1。目标是并行计算它的全部前缀聚合。空序列直接返回空输出。Exclusive scan 输出

yi=a0⊗⋯⊗ai−1,y0=e;

inclusive scan 输出 zi=yi⊗ai。本文后续算法先求 exclusive 版本,避免空前缀和单位元在边界处另设特判。

以下 work/span 按每次摘要组合、复制和节点访问的单位成本计;要得到同阶真实时间,摘要须占常数机器字,运算也须为常数时间。代数上只要求结合律,不要求交换律或逆元。若 ⊗ 不交换,左右子树的组合顺序必须始终是“左摘要 ⊗ 右摘要”;任意交换会计算另一种前缀。

Upsweep:建立归约树 ​

先把长度补到二次幂,填充值为 e。叶子按原顺序存输入;每个内部节点保存左右孩子摘要的有序组合。第 0 层并行计算相邻二元组,第 1 层并行合并长度 2 的块,直到根保存全序列摘要。

Upsweep 不变量是:高度 h 的已完成节点恰保存其连续叶区间、长度 2h 的聚合。归纳步由结合律成立;不需要把区间内部重新排序。

设补齐后长度 N=2⌈log2⁡n⌉<2n。在Work–Depth 模型中,整棵二叉树有 N−1 个内部节点,每个只做一次 ⊗,所以组合次数为 N−1,组合依赖的 span 为 ⌈log2⁡n⌉;n=1 时两者均为零,仍须处理那个输出位置。

Downsweep:传播左侧上下文 ​

把根的外部前缀设为 e。若某内部节点收到进入其区间前的前缀 p,左孩子收到 p,右孩子收到

p⊗L,

其中 L 是 upsweep 保存的左子树摘要。两个孩子随后并行继续。到叶 i 时,收到的正是 a0⊗⋯⊗ai−1。

Downsweep 不变量只承担一个重心:节点携带的是“严格位于本节点区间左侧”的聚合。右孩子加上左摘要,左孩子不加本区间任何元素,因此叶端点自然得到 exclusive 语义。

Downsweep 同样访问 O(n) 个节点、深度 O(log⁡n)。上下两遍合计

W=Θ(n),D=Θ(log⁡(n+1)).

由Brent 调度定理,P 处理器时间为 O(n/P+log⁡(n+1))。

直觉

Upsweep 先为每个连续区间建立聚合摘要,downsweep 再把“严格位于当前区间左边”的上下文从根传播到叶。每个叶最终收到自己的 exclusive 前缀;树上两个方向各只做线性工作,却把依赖链压到对数深度。

例子与边界

字符串拼接的状态轨迹 ​

取非交换运算字符串拼接,输入 a,b,c,d,单位元为空串。Upsweep 得到第一层 ab,cd,根为 abcd。Downsweep 从根前缀 "" 开始:左半收到 "",右半收到 ab;左半两叶得到 "" 与 a,右半两叶得到 ab 与 abc。

最终 exclusive 输出为 "",a,ab,abc,inclusive 输出再分别拼当前字符,得到 a,ab,abc,abcd。若在右孩子更新时写成 L⊗p,加法例子看不出错误,字符串例子会立即暴露次序颠倒。这里的字符串用于检查语义次序;若把长度为 n 的字符序列的每个前缀都复制成独立字符串,总输出长度为 Θ(n2),实际时间与空间就不再是上述单位成本摘要模型的线性界。

推论与应用

Stream compaction ​

对每个输入并行计算保留标志 bi∈{0,1},对标志做 exclusive sum scan 得到位置 pi。若 bi=1,就把元素写到输出 out[pi];保留元素总数是上扫的根总和。若下扫采用覆盖根槽的原地实现,应提前保存该总和,或在非空输入上用最后一个 pi+bi 恢复它。

因为不同保留元素的前缀计数不同,scatter 下标互异,无需并发写同一槽。Scan 在这里不仅求和,还把全局稳定压缩转换成局部位置计算;输入相对次序被保留。

内存冲突与实现 ​

概念树可单独存 2N−1 个节点(含补齐后的 N 个叶子,空间仍为 O(n)),容易满足 EREW;in-place Blelloch 布局把内部摘要写回数组指定位置,需按层核对每个槽只有一个写者。Upsweep 与 downsweep 之间必须有依赖同步,不能让后者读到未完成摘要。

在 GPU 上,warp、shared-memory bank conflict 与跨 block scan 还需分层处理。块内 scan、块总和 scan、再把块前缀加回的三阶段仍保持同一不变量,但 barrier 和全局内存流量不在抽象 work/span 中。

数值与接口边界 ​

浮点加法不满足精确结合律,树形 scan 与串行左折叠可能有不同舍入结果;这不是 data race,却会破坏 bitwise reproducibility。需要确定复现时应固定树形、使用更高精度或补偿方案。

没有单位元时仍可定义非空 inclusive scan,但标准 downsweep 的根前缀无法设值;需改算法或显式提供 identity。Segmented scan 还要在摘要中携带段首标记,不能仅在普通结果上事后清零。

参考资料
  • Guy Blelloch, Prefix Sums and Their Applications, CMU Technical Report, 1990.
  • W. Daniel Hillis, Guy Steele, Data Parallel Algorithms, Communications of the ACM, 1986.
  • Mark Harris, Shubhabrata Sengupta, John Owens, Parallel Prefix Sum (Scan) with CUDA, GPU Gems 3, 2007.
关系图谱9 个相邻概念 · 3 类关系

拖动节点调整位置。

显示关系

显示:依赖

  1. 前置三跳
  2. 前置二跳
  3. 前置一跳
  4. 当前条目
  5. 后续一跳
  6. 后续二跳
  7. 后续三跳
文字版关系按与当前条目的最短距离分组
类型化关系