这不是我的功劳,我只是为您格式化并从其他来源复制它,希望对您有所帮助
[来源:ECE 1754, Survey of Loop Transformation Techniques, Eric LaForest, March 19, 2010]
这完全是关于两次执行迭代之间的距离,在第一次中,一个外循环和内循环之间的距离为1,因此它们之间存在依赖关系。
循环倾斜正如它所说的那样:它倾斜了内部循环的执行
相对于外部的。如果内部循环依赖于阻止它并行运行的外部循环,这将很有用。例如,以下代码的依赖向量为 {(1, 0),(0, 1)} 。两个循环都不能并行化
因为它们每个都带有依赖关系。简单地交换循环只会
交换保存依赖项的索引,什么都不做。
do i = 2, n-1
do j = 2, m-1
a[i,j] =
(a[i-1,j] + a[i,j-1] + a[i+1,j] + a[i,j+1]) / 4
end do
end do
循环倾斜是通过添加外循环的索引来实现的,乘以一些
偏斜因子 f,到内部循环的边界并减去相同的值
来自内部循环索引的所有用途。减法使索引保持在
新的循环边界,保持程序的正确性。对的影响
内部循环迭代是将它们在数组中的位置向前移动 f 相对
到当前外循环,增加到外循环的依赖距离
以相同的方式。换句话说,给定一个依赖向量 (a, b),倾斜
将其转换为 (a, f a + b)。由于这种转换保留了词典
依赖关系的顺序,它总是合法的。将偏斜因子 1 应用于
上面的内部循环产生以下代码:
do i = 2, n-1
do j = 2+i, m-1+i
a[i,j-i] =
(a[i-1,j-i] + a[i,j-1-i] + a[i+1,j-i] + a[i,j+1-i]) / 4
end do
end do
这个新代码以相同的方式执行,但依赖关系为 {(1, 1),(0, 1)}。两个循环仍然带有依赖关系。但是,此时交换循环会产生依赖向量 {(1, 0),(1, 1)},如下代码所示:
do j = 4, m+n-2
do i = max(2, j-m+1), min(n-1, j-2)
a[i,j-i] =
(a[i-1,j-i] + a[i,j-1-i] + a[i+1,j-i] + a[i,j+1-i]) / 4
end do
end do
现在可以并行化内循环,因为它现在没有对 j 的循环依赖,并且对 i 的依赖由外循环携带。注意
交换倾斜循环边界不再简单:每个循环必须
考虑到另一个循环的上限和下限。