三种嵌套循环
根据边界和循环体位置
对于 Imperfect loop nest 可以通过代码优化手段将其转变为 Semi-Perfect loop nest 或者 Perfect loop nest。
在外部循环做 pipeline 可以获得最理想的 latency,但同时资源消耗也最多,因为做 pipeline的时候其内部所有的循环都会被 unroll,而其本身以及外层循环会被 flatten,
(思考:为什么上述外部循环展开后消耗的 4 个乘法器?这里的 4 是否和内层循环次数有关?这时的 Trip Count 是否为 2?)
如果对内部循环 pipeline,则会自动对循环做 LOOP_FLATTEN 优化,即把所有的嵌套循环展开(flatten)为一个大循环。上述例子中就会被展开为一个 Trip Count 为 8 的大循环,前提是 Perfect loop nest。
unroll 展开和 flatten 展开是不一样的概念。unroll 是将循环体展开为并行操作,而flatten 是将嵌套循环展开为单一循环。
规律:外部本身flatten 内部unroll
eg 矩阵乘法
只对最内层循环(即 Product 循环)做 pipeline。 可以看出这样只对外层的两个循环展开(flatten)了,最内层 Trip Count 仍然是 3,这是因为在 Col 循环里面 Product 循环外面有循环体(红色部分),所以无法应用 LOOP_FLATTEN。
如果只对第二层即 Col 循环做 pipeline,可以看出最内层的Product 循环被 unroll 了。而外面的两层循环被 flatten 了。
如果对最外层的 Row 循环做 pipeline,可以看出这个结果符合上面的描述,即:做 pipeline 的时候其内部所有的循环都会被 unroll,而其本身以及外层循环会被 flatten。
DSP48 1 3 9
对整个函数做流水,全部unroll
建议对最内部的作流水,寻求一个平衡
优化方式,增加缓存
(这样减少对原数组的访问)
Q:这样不会对cache的访问也增加了吗??