最近看论文过程中看到了关于循环分块(loop tiling)相关的内容,不太能理解。网上关于这方面的内容也不多,找了两篇论文看了下,大致知道是怎么实现的了,以下是流水账:
首先对于一个嵌套循环:
do i = 0 to N - 1 step 1
do j = 0 to N -1 step 1
do k = 0 to N - 1 step 1
A( j , k ) ;
continue
首先忽略循环 i = 0 to N-1 由于循环体并未涉及 i ,所以外层循环只是简单的对于内层循环的重复执行 ;
内层循环的维度为A(N ,N)循环块 ;
下面将该循环进行分块,分块大小为 Bj X Bk :
do jj = 0 to N-1 step Bj
do kk = 0 to N-1 step Bk
do i = 0 to N-1 step 1 //将每个分块内的内容重复计算N次 (与位置无关,可置于最外层)
do j = jj to min( jj+Bj-1 , N-1 ) step 1
do k = kk to min( kk+Bk-1 , N-1 ) step 1
A( j , k ) ;
continue ;
理解:将原始的外围循环块以Bj,Bk为单位进行分割,如jj每隔Bj大小取值一次,直到N-1,也就是将j原来的取值范围[0,N-1] 划分为以Bj为大小的多个块,kk同理;
然后在内层,对于取定的 jj ,j 的取值遍历从当前jj值开始到下一个jj值-1的所有值(step=1),这样随着外层jj值的改变,j的值就能遍历所有的[0,N-1]的值;
上述代码中的min( jj+Bj-1 , N-1 ) 的出现是因为最后一个分块长度可能不足Bj ;