MLIR的Vectorization(向量化)策略:SLP与Loop Vectorizer
从一次性能回退说起
上个月调试一个AI推理引擎的算子融合流水线,发现一个奇怪的现象:同样的计算图,在x86上跑得飞快,切到ARM Neon平台后,性能反而比纯标量还慢。抓了MLIR的-print-ir-after-all日志,发现LLVM后端生成的向量化代码里,大量extractelement和insertelement指令在循环体内来回穿插,寄存器压力直接爆表。
这个坑让我重新审视了MLIR中两个向量化策略——SLP Vectorizer和Loop Vectorizer。它们看似都能生成向量指令,但适用场景和底层机制完全不同。今天这篇笔记,就聊聊这两个策略的设计哲学、适用边界,以及我在实际调优中踩过的坑。
两个向量化引擎的底层逻辑
Loop Vectorizer:循环维度的暴力展开
Loop Vectorizer的思路很直接:把循环迭代空间按向量长度切分。比如一个处理float数组的循环,迭代次数是1024,向量宽度是4,那就生成256个向量化迭代块,每个块处理4个元素。
MLIR的Loop Vectorizer工作在affine.for或scf.for上,核心是识别循环内连续内