“floor” 步骤让我怀疑解析解不太可能,并且这实际上是一个微优化练习。这是我的想法。
暂时忽略角落和边缘,只有 3996 个需要特殊处理的单元格。
对于内部单元格,您需要添加 9 个元素来获得其下一个状态。但反过来说:每个内部单元格都必须成为 8 个加法的一部分。
或者吗?从三个连续的行
A[i]
,
B[i]
和
C[i]
开始,计算三个新行:
A'[i] = A[i-1] + A[i] + A[i+1]
B'[i] = B[i-1] + B[i] + B[i+1]
C'[i] = C[i-1] + C[i] + C[i+1]
(注意,你可以使用“滑动窗口”稍微更快地计算每个值,因为
A'[i+1] = A'[i] - A[i-1] + A[i+1]
。 运算次数相同,但加载次数较少。)
现在,要获取位置
B[j]
的新值,只需计算
A'[j] + B'[j] + C'[j]
。
到目前为止,我们还没有节省任何工作量; 我们只是重新排列了加法操作。
但是现在,在计算更新的行
B
后,您可以丢弃
A'
并计算下一行:
D'[i] = D[i-1] + D[i] + D[i+1]
您可以使用数组B'
和C'
来计算行C
的新值,而无需重新计算B'
或C'
。(当然,您会通过将行B'
和C'
移动成为A'
和B'
来实现这一点...但是这种方式更容易解释。也许。我想。)
对于每一行,比如B
,我们扫描它一次以产生B'
,执行2n
个算术运算,并再次扫描以计算更新后的B
,这也需要2n
个操作,因此总共每个元素执行四个加减法,而不是八个。
当然,在实践中,您会在更新B
时计算C'
,但操作数相同,但局部性更好。
这是我唯一的结构性想法。 SIMD优化专家可能会有其他建议...