循环展开与循环平铺

时间:2011-03-26 18:22:56

标签: c++ optimization compiler-construction nasm

有人可以告诉我们2种优化技术是相同还是不同?

此外,程序员或编译器是否有责任这样做?

2 个答案:

答案 0 :(得分:23)

这两种技术是不同的。请参阅Loop unrollingLoop tiling的说明。

完成循环展开以消除循环的开销。它(通常)仅对相当小的循环有用,其中迭代次数很少并且在编译时是已知的。它主要由编译器完成。

在较旧的时候,当计算机速度较慢且编译器更原始时,程序员会进行手动循环展开,但现在程序员这样做是不寻常的 - 除非是非常严格的嵌入式系统。

循环平铺通常用非常大的数据集完成。目标是:在一些新数据中进行分页之前,将一些数据加载到高速缓冲存储器中并对其执行所有操作。

根据正在执行的操作和数据的内部组织,一个简单的循环可能跳转到不同的数据页面,导致大量缓存未命中(和页面加载)。仔细规划执行顺序可以显着改善某些问题的运行时间。

虽然编译器可能会执行循环切片,但有时程序员可能会手动执行此循环切换,并且可能比编译器做得更好。

通常,不要尝试进行这些类型的优化,因为它们会给代码增加很多复杂性(和错误),并且通常只能提供适度的性能提升。但是,如果您的代码很慢并且分析表明特定类型的瓶颈,那么应该考虑像循环平铺这样的东西,这可能会带来很大的性能提升。

答案 1 :(得分:19)

这是两种完全不同的性能优化。

循环展开代码优化,其中代码在循环内复制,并且循环迭代的总数减少。好处是减少了循环开销(通常仅与非常小的循环相关),并且在超标量CPU中具有减少的依赖性停顿的更好的指令调度。这可以手动和/或作为编译器优化来完成。

平铺内存优化,旨在通过处理 tiles (较大数据结构中的小块)来更好地利用缓存,通常在图像或其他2D数据结构的上下文中。这通常在源代码级实现,作为算法实现的整体设计的一部分。