让 Gauss-Seidel 重新伟大:用循环展开绕过循环携带依赖
来源:loiseaujc.github.io — loiseaujc.github.io · 12 分 · by loiseaujc
📋 概述
上一篇里作者发现一个悖论:Gauss-Seidel 在数学上只需 Jacobi 一半的迭代次数就能收敛,实测却慢了四到五倍,原因是就地更新引入了循环携带依赖,编译器无法向量化。这一篇给出解法:Jacobi 每次读取的是上一轮的旧值 v,而 Gauss-Seidel 读到的 u(i-1,j) 是这一轮刚写过的新值,正是这种轮内信息传播让它收敛更快,也正是它阻止了向量化。作者用循环展开手工给编译器创造可向量化的窗口,并借助 osaca 分析流水线瓶颈。
🔑 核心要点
- 两种更新规则的差别只有一行代码,性能却差 四到五倍。
- 罪魁是循环携带依赖:u(i-1,j) 在读取时已被本轮覆写。
- 信息在单次遍历内传播既是收敛优势,也是无法向量化的原因。
- 解法是循环展开,并借助 osaca 分析流水线瓶颈。
- 作者还提示第二条路:让数学本身来引导,但更依赖具体算例。
💡 金句
一行代码的差别买来一个收敛更快的迭代法,代价却藏在收敛理论看不见的地方。
👍 0
👎 0
← 返回 Hacker News 首页