【CUDA 基础】3.5 展开循环
title: 【CUDA 基础】3.5 展开循环
categories:
- CUDA
- Freshman
tags:
- 展开归约
- 归约
- 模板函数
toc: true
date: 2018-04-19 21:02:08

Abstract: 本文介绍循环展开技术,在归约的基础上继续加速。
Keywords: 展开归约,归约,模板函数
开篇废话
博客从CSDN那边截流了一些流量,现在网站访问突然增多到让我有点不适应,于是,想想还是别总盯着流量看吧,注意文章质量,同时保证一定的更新,从数学到算法,最后到实现,优化,这些都做好,估计访问量会更多了。
到时候我就可以挂广告了,然后挣了钱吃煎饼就可以加个鸡蛋了!去网吧也能叫饮料了。。想想还有点小激动,感觉自己都有点膨胀了。
今天我们来做循环展开,GPU喜欢确定的东西,像前面讲解执行模型和线程束的时候,明确的指出,GPU没有分支预测能力,所有每一个分支他都是执行的,所以在内核里尽量别写分支,分支包括啥,包括if当然还有for之类的循环语句。
如果你不知道到为啥for算分支语句我给你写个简单到不能运行的例子:
for (itn i=0;i<tid;i++)
{
// to do something
}
如果上面这段代码出现在内核中,就会有分支,因为一个线程束第一个线程和最后一个线程tid相差32(如果线程束大小是32的话) 那么每个线程执行的时候,for终止时完成的计算量都不同,这就有人要等待,这也就产生了分支。
循环展开是一个尝试通过减少分支出现的频率和循环维护指令来优化循环的技术。
上面这句属于书上的官方说法,我们来看看例子,不止并行算法可以展开,传统串行代码展开后效率也能一定程度的提高,因为省去了判断和分支预测失败所带来的迟滞。
先来个c++ 入门循环
for (int i=0;i<100;i++)
{
a[i]=b[i]+c[i];
}
这个是最传统的写法,这个写法在各种c++教材上都能看到,不做解释,如果我们进行循环展开呢?
for (int i=0;i<100;i+=4)
{
a[i+0]=b[i+0]+c[i+0];
a[i+1]=b[i+1]+c[i+1];
a[i+2]=b[i+2]+c[i+2];
a[i+3]=b[i+3]+c[i+3];
}
没错,是不是很简单,修改循环体的内容,把本来循环自己搞定的东西,我们自己列出来了,这样做的好处,从串行较多来看是减少了条件判断的次数。
但是如果你把这段代码拿到机器上跑,其实看不出来啥效果,因为现代编译器把上述两个不同的写法,编译成了类似的机器语言,也就是,我们这不循环展开,编译器也会帮我们做。
不过值得注意的是:目前CUDA的编译器还不能帮我们做这种优化,人为的展开核函数内的循环,能够非常大的提升内核性能
在CUDA中展开循环的目的还是那两个:
- 减少指令消耗
- 增加更多的独立调度指令
来提高性能
如果这种指令
a[i+0]=b[i+0]+c[i+0];
a[i+1]=b[i+1]+c[i+1];
a[i+2]=b[i+2]+c[i+2];
a[i+3]=b[i+3]+c[i+3];
被添加到CUDA流水线上,是非常受欢迎的,因为其能最大限度的提高指令和内存带宽。
下面我们就在前面归约的例子上继续挖掘性能,看看是否能得到更高的效率。
展开的归约
完整内容参考[https://face2ai.com/CUDA-F-3-5-展开循环/])(https://face2ai.com/CUDA-F-3-5-展开循环/)
【CUDA 基础】3.5 展开循环的更多相关文章
- 【CUDA 基础】6.1 流和事件概述
title: [CUDA 基础]6.1 流和事件概述 categories: - CUDA - Freshman tags: - 流 - 事件 toc: true date: 2018-06-10 2 ...
- 【CUDA 基础】5.3 减少全局内存访问
title: [CUDA 基础]5.3 减少全局内存访问 categories: - CUDA - Freshman tags: - 共享内存 - 归约 toc: true date: 2018-06 ...
- 【CUDA 基础】5.1 CUDA共享内存概述
title: [CUDA 基础]5.1 CUDA共享内存概述 categories: - CUDA - Freshman tags: - CUDA共享内存模型 - CUDA共享内存分配 - CUDA共 ...
- 【CUDA 基础】6.2 并发内核执行
title: [CUDA 基础]6.2 并发内核执行 categories: - CUDA - Freshman tags: - 流 - 事件 - 深度优先 - 广度优先 - 硬件工作队列 - 默认流 ...
- 【CUDA 基础】5.2 共享内存的数据布局
title: [CUDA 基础]5.2 共享内存的数据布局 categories: - CUDA - Freshman tags: - 行主序 - 列主序 toc: true date: 2018-0 ...
- 【CUDA 基础】3.6 动态并行
title: [CUDA 基础]3.6 动态并行 categories: - CUDA - Freshman tags: - 动态并行 - 嵌套执行 - 隐式同步 toc: true date: 20 ...
- 【CUDA 基础】3.4 避免分支分化
- title: [CUDA 基础]3.4 避免分支分化 categories: - CUDA - Freshman tags: - 规约问题 - 分支分化 toc: true date: 2018- ...
- 【CUDA 基础】2.3 组织并行线程
title: [CUDA 基础]2.3 组织并行线程 categories: CUDA Freshman tags: Thread Block Grid toc: true date: 2018-03 ...
- CUDA基础介绍
一.GPU简介 1985年8月20日ATi公司成立,同年10月ATi使用ASIC技术开发出了第一款图形芯片和图形卡,1992年4月ATi发布了Mach32图形卡集成了图形加速功能,1998年4月ATi ...
随机推荐
- 基于全备份+binlog方式恢复数据
基于全备份+binlog方式恢复数据 将bkxt从库的全备份在rescs5上恢复一份,用cmdb操作 恢复全备后执行如下操作 set global read_only=OFF; stop slave; ...
- T100——自动执行设置了但没执行
azzi950设置了背景定时执行,但到底没执行, 重启的命令如下.三个命令都执行一下.指令 1: r.r azzp950 kill 指令 2: r.r azzp951 kill 指令 3: r.r a ...
- 【计数dp】Array Without Local Maximums
参考博客:[CF1068D]Array Without Local Maximums(计数DP) [题意] n<=1e5 dp[i][j][k]表示当前第i个数字为j,第i-1个数字与第i个之间 ...
- PyQt5创建多线程
参阅: https://blog.csdn.net/chengmo123/article/details/96477103 https://www.cnblogs.com/zhuminghui/p/9 ...
- [Jenkins]初次访问Jenkins,输入密码后,页面卡在空白界面一直未加载出内容_解决方案
问题描述 安装Jenkins,初次访问Jenkins(http://localhost:8002,端口号根据各自设置而不同,本例是8002),输入Jenkins初始化的管理密码之后,浏览器中一直卡在空 ...
- 【原创】大叔案例分享(5)id打通
经常有一些需要做id打通的场景,比如用户id打通等, 问题抽象是每条数据都可以解析出一个或多个kv pair:(id_type,id),然后需要将某一个kv pair匹配的多条数据进行merge: 比 ...
- 【weixin】微信支付---Native支付模式一
[模式一]:商户后台系统根据微信支付规则链接生成二维码,链接中带固定参数productid(可定义为产品标识或订单号).用户扫码后,微信支付系统将productid和用户唯一标识(openid)回调商 ...
- warning LNK4076: 无效的增量状态文件“../×××.ilk”;正在非增量链接
VS编译警告:warning LNK4076: 无效的增量状态文件“../×××.ilk”;正在非增量链接 解决方法:删除程序提示的输出目录的×××.ilk,重新编译,即可
- Struts的相关基础
为什么要用struts? 1.该框架基予mvc的开发设计模式上的,所以拥有mvc的全部优点,他在M.V.C上都有涉及,但它主要是提供一个好的控制器和一套定制的标签库上,有mvc的一系列优点:层次分明, ...
- sql的关键字
整理一下sql的关键字,一直都在用,只是很少去整理,所以今天简单整理一下,主要是整理CRUD的一些关键字. 写在前面:sql 不区分大小写 select 简单查询语句 select columnNam ...