Manycore Programming: CUDA 2

在上一节,我们只是谈到了CUDA的用法,但是实际上很多高级的优化的技巧并没有涉及,所以本讲针对带宽、指令、调度的最大化吞吐量三个方面进行优化。通过举一个例子让这些优化过程更加清晰。

最优存储设计

SOA vs AOS

这里写图片描述

哪一种更好呢?其实要看具体情况,比如:
这里写图片描述

以上的话使用SOA更好。

这里写图片描述

这种情况下,使用AOS更好。

存储对齐

在对DRAM的数据进行存取的时候,一般是取整个segment的数据。如果把很多次的取内存放在一次取数据的时候,就可以产生比较高的带宽。

这里写图片描述

使用共享存储

  • 把数据从DRAM搬运到共享存储
  • 进行同步
  • 在共享存储上对数据进行存取
  • 进行同步
  • 把数据写回DRAM

这里写图片描述

使用double buffer可以使得效率更高:
这里写图片描述

使用共享存储有两种方式:一种是在编译时固定共享存储的大小,另外一种就是在运行的时候使用。
这里写图片描述

存储bank 冲突

当多个线程对同一个bank的不同32 bit的字进行访问的时候,会发生冲突。

比如在下面这个例子里,左边的和最右边的都没有冲突,冲突发生在中间的。中间的存在两个线程访问统一个bank。

这里写图片描述

那么怎么消除冲突呢?

这里写图片描述

最左边的采用的是随机排列的方法,中间的是多个线程指向同一个bank的word,最右边的是所有的线程指向同一个bank的word。

补全

使用补全的方式使得存储对齐,方便操作。比如是63字节对齐,那么就给存储的区域补全到64字节对齐。

最大化指令吞吐量

branch divergence

每次指令执行时候,SIMT就会选择一个warp进行执行,每个warp的最高效率就是32个线程一起执行。

一般来说,指令越少的话,每个线程就能更快执行。因为需要等待warp里的线程执行结束以后,才能回到原来的轨迹继续执行下去。所以每个线程执行得越快,就能越快回到正常的执行轨迹上。但是有的条件判断使得轨迹边长,为了提高吞吐量,需要做一些优化。比如下面的程序:

这里写图片描述

optimizing to mix

做循环展开可以提高IPC,具体使用unroll的方法如下:

这里写图片描述

最大化调度吞吐量

就是在使用资源方面,看资源使用率。

使用intrinsic 函数提高performance。

这里写图片描述

优化算法

数据并行算法

Map

映射就是给了一个list,然后通过一个函数得到一个新的list并返回。

映射这部分和别的部分不相关,无交集。并不会受到别的函数的影响。

这里写图片描述

Reduce

就是把线性执行的比如加法,减法变成通过集合律变成二分类型。

这里写图片描述

reduce会存在问题,他使得线程的利用率下降而且不均匀分布。比如随着线程数量减少,只需要一个block可以搞定,但是现在它占据了好几个block,占据了资源,影响了速度。

这里写图片描述

把上面的东西改成:
这里写图片描述

通过哈希映射把多个线程到了同一个线程。

以上步骤还有同步线程的操作,非常耗时间,所以改成:
这里写图片描述

Scan

就是对list进行累计操作,比如累加。

那么怎么减少访问次数呢?

这里写图片描述

这里写图片描述

数据并行算法的步骤

compact(压缩)

对原数组处理产生更小的数组。

这里写图片描述

find unique(找到独特的项)

去除冗余,找到独特的。

这里写图片描述

建立flag array

就是在去除冗余的时候,建立哈希表去除冗余。比如一个字符串中是否出现某个字符。

直接只用一个数组记录,0为没有,1为有。这是非常简单的编程思路。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值