循环优化与多面体模型

循环通常是数据并行应用的最密集计算段,因此循环优化直接影响性能。当面对嵌套循环时,分配给线程的计算粒度将直接影响性能。循环转换如Fission(循环裂变)与Fusion(循环融合)的嵌套式循环可促使并行化,并提高工作效率。

本文就几种循环优化的方法与多面体模型的调度进行简要阐述(因为LZ已经被这些循环优化搞得痛不欲生了)。


Loop fusion

顾名思义,该变换令循环进行了融合。如图所示,原始代码是两个for循环,变化之后,对两个循环中 i、j 相同的范围进行了融合。
在这里插入图片描述
我们为了把该变换映射或者说调度到多面体模型中去,需要产生调度树。

举例如下:
在这里插入图片描述
有这样一段用TC写的代码,语句S、T分别为循环语句。其融合操作表述如下:
在这里插入图片描述
Band 操作将S、T所对应的迭代向量进行了融合。


Loop tiling

Loop tiling/blocking 的意思是分块,可以将循环的迭代空间划分为更小的块,以帮助确保循环中使用的数据在重用之前一直保存在缓存中。循环迭代空间的划分导致将大数组划分为更小的块,从而将被访问的数组元素匹配到缓存大小中,增强缓存重用,消除缓存大小需求。

平常的循环:

for(i=0; i<N; ++i){
  ...
}

变换后的循环,拥有一个全新的 block 大小B:

for(j=0; j<N; j+=B){
  for(i=j; i<min(N, j+B); ++i){
    ....
  }
}

更具体的例子:
在这里插入图片描述
下面是一个矩阵向量乘法的例子。有三个数组,每个数组有100个元素。代码没有将数组划分为更小的大小。

  int i, j, a[100][100], b[100], c[100];
  int n = 100;
  for (i = 0; i < n; i++) {
    c[i] = 0;
    for (j = 0; j < n; j++) {
      c[i] = c[i] + a[i][j] * b[j];
    }
  }

当我们应用循环分块,使用2 * 2块,代码变为:

  int i, j, x, y, a[100][100], b[100], c[100];
  int n = 100;
  for (i = 0; i < n; i += 2) {
    c[i] = 0;
    c[i + 1] = 0;
    for (j = 0; j < n; j += 2) {
      for (x = i; x < min(i + 2, n); x++) {
        for (y = j; y < min(j + 2, n); y++) {
          c[x] = c[x] + a[x][y] * b[y];
        }
      }
    }
  }

原来的循环迭代空间n×n。数组的访问块(i, j)也是n×n。当n过大和机器的缓存容量太小,访问数组元素的循环迭代(例如,i = 1, j = 1到n)可能交叉的高速缓存线路,导致缓存丢失。

  • 7
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

wangbowj123

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值