在计算机科学和编译器设计中,回圈交替(Loop Nest Optimization, LNO)是一种优化技术,主要透过一系列回圈转换来达到局部性优化、平行化或减少其他回圈开销。这种技术特别适用于处理嵌套回圈的场景,其中一个回圈内包含另一个回圈。基础的应用之一是降低内存访问延迟或对于一些常见的线性代数算法所需的快取带宽。
回圈交替的技术可以显著提升多核处理器的效能,通过提升资料在快取中的重用率来达到更高效率。
回圈交替通常使用一种称为「回圈切块」的策略,也就是将回圈的迭代空间划分成更小的区块,从而确保回圈中使用的数据在重用之前能够保持在快取中。这种划分可以帮助将大型数组分割成较小的区块,进而适配快取的大小,增强快取的重用性并消除对快取大小的要求。
一个经典的例子是矩阵-向量乘法。在这个例子中,有三个数组,每个数组包含100个元素。原始代码并没有将数组分割成较小的区块,经由应用2 x 2的回圈切块后,代码会变得更有效率。当原始的迭代空间过大,而机器的快取大小又不足时,这种情况会导致访问的数组元素跨越快取行,从而造成快取未命中。
选择合适的切块大小是提升性能的关键,但这通常需要对快取大小和被访问数组区域进行准确的估计。
确定最佳的切块大小并不容易,因为这需要考虑到访问数组的区域和目标机器的快取大小。此外,回圈的嵌套顺序(即回圈互换)对提高快取性能也起着至关重要的作用。显式切块需要根据这些因素选择一个合适的块大小,相较之下,快取无关的算法则旨在无需显式切块的情况下有效利用快取。
在计算机上,很多大型数学操作经常涉及矩阵乘法。基本的运算表达为 C = A × B,其中 A、B 和 C 都是 N x N的数组。为了解决运算中的几个问题,我们需要进行多次平行的浮点加法运算,保证加法器的多周期延迟能够持续运行。传统PC的记忆体系统通常每进行一次乘法加法操作只能进行一次内存操作,这就要求加载的值必须至少重用两次。因此,在计算一个运算结果的同时,能够提高重用的策略至关重要。
在处理大型数据运算时,优化算法的性能常常受限于内存带宽和所需的寄存器数量。
继续探索进一步的优化,对于特定硬体的记忆体系统,对回圈进行多级切块(针对寄存器、L1和L2快取)能有效地减少所需的内存带宽。随着计算需求的不断增加,这些细微的调整将使得我们能够在更高的性能范畴中运行复杂的算法,而不仅仅是依赖于单一的快取级别。
回圈交替技术的深度 利用不光限于单一的运算范畴,它的效能在多核处理器中得到了惊人的提升,促使计算机科学的发展朝向更高的效率和快速的计算边界迈进。那么,在未来,这种技术如何继续推动计算性能的进步呢?