- 1、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
- 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
- 4、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
- 5、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们。
- 6、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
- 7、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
本章引入了CUDA
本章引入了CUDA 编程模型背后的主要概念,方式是概述它们是怎样使用C 语言表示的。
CUDA3.0
编程模型
更多的关于
更多的关于CUDA C 的描述在 3.2 节。
本章使用的向量相加例子的完整代码和下一个例子可在SDK 中的vectorAdd代码样本中
本章使用的向量相加例子的完整代码和下一个例子可在SDK 中的vectorAdd代码样本中
找到。
找到。
2.1 内核
2.1 内核
CUDA 通过允许程序员定义称为内核的C 函数扩展了C,内核调用时会被N 个 CUDA 线程
CUDA 通过允许程序员定义称为内核的C 函数扩展了C,内核调用时会被N 个 CUDA 线程
执行
执行 N 次(注:这句话要好好理解,其实每个线程只执行了一次),这和普通的 C 函数只执行
一次不同。
一次不同。
内核使
内核使用 global 声明符定义,使用一种新...执行配置语法指定执行某一指
定内核调用的线程数(参看附录B.13)。每个执行内核的线程拥有一个独一无二的线程ID,
定内核调用的线程数(参看附录B.13)。每个执行内核的线程拥有一个独一无二的线程ID,
可以通过内置的threadIdx 变量在内核中访问。
可以通过内置的threadIdx 变量在内核中访问。
下面的样本代码将两个长度为N 的向量A 和 B 相加,并将结果存入向量C 中。
下面的样本代码将两个长度为N 的向量A 和 B 相加,并将结果存入向量C 中。
// Kernel definition
global void VecAdd(float* A, float* B, float* C)
{
int i = threadIdx.x; C[i] = A[i] + B[i];
}
int main()
{
...
// Kernel invocation with N threads
这里,N 个线程中的每一个执行VecAdd()的一次成对加法。
这里,N 个线程中的每一个执行VecAdd()的一次成对加法。
2.2 线程层次
2.2 线程层次
为简便起见,
为简便起见,threadIdx 是一个有 3 个部件的向量,所以线程可以使用一维,二维,三
维索引标识,形成一维,二维,三维的线程块。这提供了一种自然的方式来调用作用在域内
维索引标识,形成一维,二维,三维的线程块。这提供了一种自然的方式来调用作用在域内
元素上的计算,如向量,矩阵,体元(volume)。
元素上的计算,如向量,矩阵,体元(volume)。
线程索引和线程
线程索引和线程ID 直接相关:对于一维的块,它们相同;对于二维长度为(Dx,Dy)的块,
线程索引为(x,y)的线程ID 是(x+yDx);对于三维长度为(Dx,Dy,Dz)的块,索引为(x,y,z)的
线程索引为(x,y)的线程ID 是(x+yDx);对于三维长度为(Dx,Dy,Dz)的块,索引为(x,y,z)的
线程
线程 ID 为(x+yDx+zDxDy)。
下面的例子代码将两个长度为N*N 的矩阵A 和B 相加,然后将结果写入矩阵C。
下面的例子代码将两个长度为N*N 的矩阵A 和B 相加,然后将结果写入矩阵C。
// Kernel definition
global void MatAdd(float A[N][N], float B[N][N], float C[N][N])
{
int i = threadIdx.x; int j = threadIdx.y;
C[i][j] = A[i][j] + B[i][j];
}
由于块内的所有线程必须存在于同一个处理器核心中且共享该核心有限的存储器资源,int main() {
由于块内的所有线程必须存在于同一个处理器核心中且共享该核心有限的存储器资源,
int main() {
...
// Kernel invocation with one block of N * N * 1 threads int numBlocks = 1;
dim3 threadsPerBlock(N, N);
因此,一个块内的线程数目是有限的。在目前的
因此,一个块内的线程数目是有限的。在目前的 GPU 上,一个线程块可以包含多达 512 个线
程。
程。
然而,一个内核可被多个同样大小的线程块执行,所以总的线程数等于每个块内的线程
然而,一个内核可被多个同样大小的线程块执行,所以总的线程数等于每个块内的线程
数乘以线程块数。
数乘以线程块数。
线程块被组织成一维或二维的线程网格,如图
线程块被组织成一维或二维的线程网格,如图 2-1 所示。一个网格内的线程块数往往由
被处理的数据量而不是系统的处理器数决定,前者往往远超后者。
被处理的数据量而不是系统的处理
原创力文档


文档评论(0)