我理解GCD如何在一个简单的例子上工作如下:
for(i=1; i<=100; i++)
{
X[2*i+3] = X[2*i] + 50;
}
我们首先将其转换为以下形式:
X[a*i + b]
和X[c*i + d]
a=2
,b=3
,c=2
,d=0
以及GCD(a,c)=2
和(d-b)
为-3
。由于2
不会划分-3
,因此无法实现依赖。
但是我们怎样才能在双重嵌套循环上进行GCD测试呢?
例如:
for (i=0; i<10; i++){
for (j=0; j<10; j++){
A[1+2*i + 20*j] = A[2+20*i + 2*j);
}
}
答案 0 :(得分:2)
在嵌套循环的情况下应用GCD的“简单”方法是仅在数组本身是多范围的情况下应用它;即,原始源代码使用多个下标而不是已经线性化的表达式。当然,如果你可以“反向转换”这些线性化的下标,那么你将拥有相同的。
一旦您将问题转换为多元问题,那么您可以简单地应用GCD测试“维度尺寸”。如果任何维度显示没有依赖性,那么你可以停止并声明对整个multidemsional下标序列没有依赖。
关键当然是作为一个多维索引问题的转换为您提供了一个很好的属性,即在各个索引值和相应的索引表达式元组之间存在一对一的映射。没有这个,问题就更难了。
这是我在70年代在ASC Fortran矢量化编译器中采用的方法,它工作得很好,特别是与非相交情况的方向下标分析结合使用。 GCD测试本身并不足够,但它确实为您提供了一种相对便宜的方法,可以在您可以避免更昂贵的依赖性分析的情况下在分析中做出早期决策。
答案 1 :(得分:2)
虽然可以对下标进行去线,但GCD测试很容易直接应用。在您的示例中,下标对为[1+2*i + 20*j]
和[2+20*i + 2*j]
,因此我们正在寻找等式的整数解
1 + 2*i + 20*j = 2 + 20*i' + 2*j'
重新排列,我们得到
2*i - 20*i' + 20*j - 2*j = 1
计算所有系数的GCD,2,-20,20和-2,看它是否除以常数。在这种情况下,GCD是2.因为2不分1,所以没有依赖。