CUDA中Scan算法的实现与优化
1. Scan算法与电路设计
Scan算法有多种并行实现方式。在思考其他可能的实现时,可借鉴整数加法硬件的设计方法,因为其与Scan算法功能类似。硬件加法器传播部分加法结果,最终得到用于多精度算术的进位位,而Scan算法则是在数组中传播任意二元关联运算符,最终得到归约结果。
硬件设计师使用有向无环图来表示不同的Scan“电路”实现,这些图能简洁地表达数据流和并行性。需要注意的是,电路图示通常展示的是包含扫描(inclusive scan),而非排除扫描(exclusive scan)。若要将包含扫描转换为排除扫描,只需将0连接到第一个输出,并将总和连接到输出即可。
Scan算法中的Blelloch算法对应一种名为Brent - Kung的电路设计。Brent - Kung电路是一种递归分解电路,每第二个输出会输入到宽度减半的Brent - Kung电路中。该电路的扇出(fan - out)恒定为2。其深度随输入数量呈对数增长,比串行算法更高效,但并非最小深度电路。
Sklansky提出了一种构建最小深度电路的方法,通过递归分解,并行运行两个(N/2)输入电路,并将左电路的脊柱(spine)输出添加到右电路的每个元素上。另一种最小深度扫描电路Kogge - Stone,其扇出也恒定为2,但有许多操作节点,软件实现效率较低。
任何扫描电路都可由扫描(执行并行前缀计算并生成输入数组的总和作为输出)和扇(将输入添加到其余输出中的每个元素)组合而成。对于优化的CUDA实现,一个关键见解是扇的输入不一定来自Scan,任何归约操作都可以。例如,将输入数组拆分为长度为b的子数组,使用优化的归约例程计算每个子数组的总和,得
超级会员免费看
订阅专栏 解锁全文
362

被折叠的 条评论
为什么被折叠?



