CUDA Pro Tip: Write Flexible Kernels with Grid-Stride Loops
https://devblogs.nvidia.com/cuda-pro-tip-write-flexible-kernels-grid-stride-loops/
One of the most common tasks in CUDA programming is to parallelize a loop using a kernel. As an example, let’s use our old friend SAXPY. Here’s the basic sequential implementation, which uses a for loop. To efficiently parallelize this, we need to launch enough threads to fully utilize the GPU.
CUDA编程最常见的任务之一就是用一个kernel来并行化一个循环。比如,对于我们老朋友SAXPY,下面是一个基础的使用循环的实现。为了效率地并行化它,我们需要运行大量的线程来充分利用GPU。
void saxpy(int n, float a, float *x, float *y)
{
for (int i = ; i < n; ++i)
y[i] = a * x[i] + y[i];
}
Common CUDA guidance is to launch one thread per data element, which means to parallelize the above SAXPY loop we write a kernel that assumes we have enough threads to more than cover the array size.
通常CUDA指引会为每一个数据元素运行一个线程,意味着要并行化上述的SAXPY循环,我们需要假设我们写的kernel要有足够的线程以满足数组的大小。
__global__
void saxpy(int n, float a, float *x, float *y)
{
int i = blockIdx.x * blockDim.x + threadIdx.x;
if (i < n)
y[i] = a * x[i] + y[i];
}
I’ll refer to this style of kernel as a monolithic kernel, because it assumes a single large grid of threads to process the entire array in one pass. You might use the following code to launch the saxpy kernel to process one million elements.
我称这类kernel为monolithic kernel,因为它假设存在单个大的线程网格在一次同时处理,运行整个数组运算。你需要用下面的代码来运行一个具有百万元素的saxpy kernel
// Perform SAXPY on 1M elements
saxpy<<<,>>>(<<, 2.0, x, y);
Instead of completely eliminating the loop when parallelizing the computation, I recommend to use a grid-stride loop, as in the following kernel.
相比在并行化计算时完全消去循环,我更推荐使用一种grid-stride loop,如下
__global__
void saxpy(int n, float a, float *x, float *y)
{
for (int i = blockIdx.x * blockDim.x + threadIdx.x;
i < n;
i += blockDim.x * gridDim.x)
{
y[i] = a * x[i] + y[i];
}
}
Rather than assume that the thread grid is large enough to cover the entire data array, this kernel loops over the data array one grid-size at a time.
比起假设线程网格足够大得覆盖整个数组,这个kernel运行一次,就对数组进行一个grid-size的循环。
Notice that the stride of the loop is blockDim.x * gridDim.x which is the total number of threads in the grid. So if there are 1280 threads in the grid, thread 0 will compute elements 0, 1280, 2560, etc. This is why I call this a grid-stride loop. By using a loop with stride equal to the grid size, we ensure that all addressing within warps is unit-stride, so we get maximum memory coalescing, just as in the monolithic version.
注意到这个循环的跨度是 blockDim.x * gridDim.x,它是一个线程网格中所有线程的数量。如果该线程网格中有1280个线程,那么编号为0的线程将执行元素0,1280,2560……这就是为什么我称之为“grid-stride loop”。使用一个跨度等于网格大小的循环,我们可以保证了所有地址都是unit-stride的,于是我们比起monolithic的版本减少了最大的内存消耗。
When launched with a grid large enough to cover all iterations of the loop, the grid-stride loop should have essentially the same instruction cost as the ifstatement in the monolithic kernel, because the loop increment will only be evaluated when the loop condition evaluates to true.
grid-stride循环比起monolithic kernel,也会需要相同的计算消耗在if语句上,因为循环的条件为真时循环才会继续进行(在这里隐式地产生了if的消耗)。
There are several benefits to using a grid-stride loop.
1.Scalability and thread reuse. By using a loop, you can support any problem size even if it exceeds the largest grid size your CUDA device supports. Moreover, you can limit the number of blocks you use to tune performance. For example, it’s often useful to launch a number of blocks that is a multiple of the number of multiprocessors on the device, to balance utilization. As an example, we might launch the loop version of the kernel like this.
1.稳定性及线程复用。当使用一个循环,你可以支持任何显存大小的运算甚至包括它超出了CUDA设备(一次性)支持的最大值。除此之外,你可以限制线程块数量来调整运行效率。比如,为平衡资源使用,载入一定数量的具有不同multiprocessors的线程块,是非常有用的。
int numSMs;
cudaDeviceGetAttribute(&numSMs, cudaDevAttrMultiProcessorCount, devId);
// Perform SAXPY on 1M elements
saxpy<<<*numSMs, >>>( << , 2.0, x, y);
CUDA Pro Tip: Write Flexible Kernels with Grid-Stride Loops的更多相关文章
- CUDA Pro Tip: Optimized Filtering with Warp-Aggregated Atomics
In this post, I’ll introduce warp-aggregated atomics, a useful technique to improve performance when ...
- CUDA Pro:通过向量化内存访问提高性能
CUDA Pro:通过向量化内存访问提高性能 许多CUDA内核受带宽限制,而新硬件中触发器与带宽的比率不断提高,导致带宽受限制的内核更多.这使得采取措施减轻代码中的带宽瓶颈非常重要.本文将展示如何在C ...
- cuda编程-卷积优化
CUDA Convolution https://www.evl.uic.edu/sjames/cs525/final.html Improve Image Processing Using GPU ...
- CUDA 8混合精度编程
CUDA 8混合精度编程 Mixed-Precision Programming with CUDA 8 论文地址:https://devblogs.nvidia.com/mixed-precisio ...
- Ext.js中的tip事件实际使用
Ext.onReady(function () { // Init the singleton. Any tag-based quick tips will start working. Ext.ti ...
- CUDA学习笔记(二)——CUDA线程模型
转自:http://blog.sina.com.cn/s/blog_48b9e1f90100fm5b.html 一个grid中的所有线程执行相同的内核函数,通过坐标进行区分.这些线程有两级的坐标,bl ...
- ExtJs 4: How To Add Grid Cell Tooltip
最近忙一个项目的时候需要实现鼠标移到grid的某一行上提示消息.花了半天时间才解决.在网上找很久终于有找到一个有用的.我的版本是extjs4. 效果如图 Ext.onReady(function () ...
- CUDA性能优化----warp深度解析
本文转自:http://blog.163.com/wujiaxing009@126/blog/static/71988399201701224540201/ 1.引言 CUDA性能优化----sp, ...
- Linux下Qt+CUDA调试并运行
Qt与CUDA相结合具体的操作主要修改qt项目中的配置文件pro.下面以测试的项目为例. 因为这是一个测试案例,代码很简单,下面将这几个文件的代码贴出来,方面后面对应pro文件和Makefile文件中 ...
随机推荐
- 洛谷-P3809-后缀排序(后缀数组)
看了求后缀数组的倍增法之后很快就理解了,但是自己写的倍增法用map排序还是超时了.然后看了两天别人写的模板,题目是通过了,但感觉代码还是半懂半背的.以后多熟悉熟悉吧: 后缀数组 #include &q ...
- Trailing Zeroes (III) LightOJ - 1138 二分+找规律
Time Limit: 2 second(s) Memory Limit: 32 MB You task is to find minimal natural number N, so that N! ...
- Spring Boot 之 Redis详解
Redis是目前业界使用最广泛的内存数据存储. Redis支持丰富的数据结构,同时支持数据持久化. Redis还提供一些类数据库的特性,比如事务,HA,主从库. REmote DIctionary S ...
- <USACO09FEB>庙会捷运Fair Shuttleの思路
一个没有被我成功证明的 贪心 但是 ac了的 别人排序都是排终点.但我的排终点错了emm排起点才对qvq 有没有人友情看看怎么证(没有 #include<cstdio> #include& ...
- win10 安装VMware Workstation Pro提示无法在windows上运行
win10 安装vm无法在windows上运行 之前还可以用 网上搜了一下 要安装最新15.5.0就不会报错了 没毛病!! 不想注册下载 百度网盘(2019年9月19日版本) https://pan ...
- Dykin's blog
回归分析是一种很重要的预测建模技术.主要是研究自变量与因变量之间的因果关系.本文将会从数学角度与代码角度分析不同类型的回归.当你想预测连续型的非独立变量,或者对一系列独立变量或输入项有所反应时,就会使 ...
- vmware增加新硬盘无需重启生效
echo "scsi add-single-device 2 0 2 0" > /proc/scsi/scsi # echo "scsi add-single-de ...
- 当鼠标hover的时候,使用tip将overflow:hidden隐藏的文字显示完全
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...
- Leetcode 142题 环形链表 II(Linked List Cycle II) Java语言求解
题目描述: 给定一个链表,返回链表开始入环的第一个节点. 如果链表无环,则返回 null. 为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始). 如果 p ...
- 优秀的Spring Cloud开源项目整理推荐
无论是对于初学者,还是有一定工作经验的程序员来讲,Spring Cloud开源项目都是一笔宝贵的财富.下面给大家整理了十个优秀的开源项目,分别是spring-cloud-examples.spaasc ...