关于优化:循环中心的x+=y是否总是导致写后读数据依赖性,从而阻止矢量化



我的问题是:

关于。优化:循环中心的x+=y是否总是导致写后读数据依赖性,从而阻止矢量化

请参阅https://cvw.cac.cornell.edu/vector/coding_dependencies

写入后读取("流"或"RAW"(依赖关系这种依赖关系是不可向量化的。当值涉及特定循环迭代("读取"(的变量的在先前的循环迭代("写入"(中确定。换句话说,读取变量(用作数学运算的操作数(在其值已由先前循环迭代修改之后。

这个问题非常普遍,因为它基本上是在问在循环的中心使用+=运算符是否会导致写后读取("流"或"RAW"(数据依赖性,从而排除矢量化。

例如。

for(i...){
for(j...){
x(i,j) += y(i,j)
} 
}

请参阅https://gcc.gnu.org/projects/tree-ssa/vectorization.html示例14:双重还原:

在您的示例中,假设数组彼此之间没有别名,则数据依赖性没有问题:由于每个x(i,j)值仅依赖于y(i,j),并且y(i,j)仅在循环中读取,因此可以轻松安全地向量化循环。如果xy重叠,则将循环矢量化要困难得多,因为它导致x(i,j)值的计算之间的隐式依赖性(因为y(i,j)可以与之前计算的x(i-1,j)别名(。

通常,如果存在依赖链(因为顺序顺序主要是唯一可能的顺序(,则自动矢量化非常困难,甚至不可能。所提供的文章提到了这样一种情况(由于数据依赖性,每个操作都需要计算前一个操作(。这与特定的+=运算符无关。这一切都是关于数据依赖性(或任何循环携带的依赖性(。


注释

关于浮点(FP(数,默认情况下操作不是关联的,因此无法以矢量化的方式执行类似x(0) + x(1) + x(2) + ...的操作(如果x是FP数的数组(。实际上,唯一可能的正确顺序是基于IEEE-754标准的((x(0) + x(1)) + x(2)) + ...。编译器选项可用于将FP运算视为关联运算,以便能够以矢量化的方式执行此类计算。这打破了IEEE-754标准和一些要求顺序不改变的代码(例如Kahan求和(。另外请注意,虽然上面的表达式可以向量化(请参阅并行扫描(,但它在大多数主流CPU上通常还不是很有效。还有一些硬件可以从并行扫描中受益:主流的离散GPU。

最新更新