CUDA刷新器:CUDA编程模型
CUDA刷新器:CUDA编程模型
CUDA Refresher: The CUDA Programming Model
CUDA,CUDA刷新器,并行编程
这是CUDA更新系列的第四篇文章,它的目标是刷新CUDA中的关键概念、工具和初级或中级开发人员的优化。
CUDA编程模型提供了GPU体系结构的抽象,它充当了应用程序与其在GPU硬件上的可能实现之间的桥梁。这篇文章概述了CUDA编程模型的主要概念,概述了它如何在通用编程语言如C/C++中暴露出来。
介绍一下CUDA编程模型中常用的两个关键词:主机和设备。
主机是系统中可用的CPU。与CPU相关联的系统内存称为主机内存。GPU被称为设备,GPU内存也被称为设备内存。
要执行任何CUDA程序,有三个主要步骤:
将输入数据从主机内存复制到设备内存,也称为主机到设备传输。
加载GPU程序并执行,在片上缓存数据以提高性能。
将结果从设备内存复制到主机内存,也称为设备到主机传输。
CUDA内核和线程层次结构
图1显示了CUDA内核是一个在GPU上执行的函数。应用程序的并行部分由K个不同的CUDA线程并行执行k次,而不是像常规C/C++函数那样只进行一次。

Figure 1. The kernel is a function executed on the GPU.
每一个CUDA内核都以一个__global__声明说明符开头。程序员通过使用内置变量为每个线程提供唯一的全局ID。

图2. CUDA内核被细分为块。
一组线程称为CUDA块。CUDA块被分组到一个网格中。内核作为线程块的网格来执行(图2)。
每个CUDA块由一个流式多处理器(SM)执行,不能迁移到GPU中的其他SMs(抢占、调试或CUDA动态并行期间除外)。一个SM可以根据CUDA块所需的资源运行多个并发CUDA块。每个内核在一个设备上执行,CUDA支持一次在一个设备上运行多个内核。图3显示了GPU中可用硬件资源的内核执行和映射。

图3. 在GPU上执行内核。
CUDA为线程和块定义了内置的三维变量。线程使用内置的三维变量threadIdx编制索引。三维索引提供了一种自然的方法来索引向量、矩阵和体积中的元素,并使CUDA编程更容易。类似地,块也使用名为blockIdx的内置三维变量编制索引。
以下是几个值得注意的要点:
CUDA架构限制每个块的线程数(每个块限制1024个线程)。
线程块的维度可以通过内置的blockDim变量在内核中访问。
syncu中的线程可以使用syncu函数同步。使用同步线程时,块中的所有线程都必须等待,然后才能继续。
在<<…>>>语法中指定的每个块的线程数和每个网格的块数可以是int或dim3类型。这些三角括号标记从主机代码到设备代码的调用。它也被称为内核启动。
下面用于添加两个矩阵的CUDA程序显示多维blockIdx和threadIdx以及blockDim等其他变量。在下面的例子中,为了便于索引,选择了一个2D块,每个块有256个线程,x和y方向各有16个线程。使用数据大小除以每个块的大小来计算块的总数。
// Kernel - Adding two matrices MatA and MatB
__global__ void MatAdd(float MatA[N][N], float MatB[N][N],
float MatC[N][N])
{
int i = blockIdx.x * blockDim.x + threadIdx.x;
int j = blockIdx.y * blockDim.y + threadIdx.y;
if (i < N && j < N)
MatC[i][j] = MatA[i][j] + MatB[i][j];
}
int main()
{
...
// Matrix addition kernel launch from host code
dim3 threadsPerBlock(16, 16);
dim3 numBlocks((N + threadsPerBlock.x -1) / threadsPerBlock.x, (N+threadsPerBlock.y -1) / threadsPerBlock.y);
MatAdd<<<numBlocks, threadsPerBlock>>>(MatA, MatB, MatC);
...
}
Memory hierarchy
支持CUDA的GPU有一个内存层次结构,如图4所示。

图4. gpu中的内存层次结构。
以下内存由GPU架构公开:
这些寄存器对每个线程都是私有的,这意味着分配给线程的寄存器对其他线程不可见。编译器决定寄存器的利用率。
一级/共享内存(SMEM)-每个SM都有一个快速的片上草稿行内存,可用作一级缓存和共享内存。CUDA块中的所有线程都可以共享共享内存,在给定SM上运行的所有CUDA块都可以共享SM提供的物理内存资源。。
只读内存每个SM都有一个指令缓存、常量内存、纹理内存和对内核代码只读的RO缓存。
二级缓存二级缓存在所有SMs中共享,因此每个CUDA块中的每个线程都可以访问该内存。nvidiaa100 GPU已经将二级缓存大小增加到40mb,而v100gpu中只有6mb。
全局内存这是位于GPU中的GPU和DRAM的帧缓冲区大小。
NVIDIA CUDA编译器在优化内存资源方面做得很好,但专家CUDA开发人员可以选择有效地使用这种内存层次结构来优化CUDA程序。
计算能力
GPU的计算能力决定了GPU硬件支持的通用规范和可用特性。此版本号可由应用程序在运行时使用,以确定当前GPU上可用的硬件功能或指令。
每个GPU都有一个版本号,表示为X.Y,其中X包括主要修订号,Y包含次要修订号。小版本号对应于架构的增量改进,可能包括新特性。
有关任何支持CUDA的设备的计算能力的更多信息,请参阅CUDA示例代码设备查询。此示例枚举系统中存在的CUDA设备的属性。
摘要
CUDA编程模型提供了一种异构环境,其中主机代码在CPU上运行C/C++程序,内核在物理上分离的GPU设备上运行。CUDA编程模型还假设主机和设备都保持各自独立的内存空间,分别称为主机内存和设备内存。CUDA代码还通过PCIe总线提供主机和设备内存之间的数据传输。
CUDA还公开了许多内置变量,并提供了多维索引的灵活性,以简化编程。CUDA还管理不同的内存,包括寄存器、共享内存和一级缓存、二级缓存和全局内存。高级开发人员可以有效地使用这些内存来优化CUDA程序。
CUDA刷新器:CUDA编程模型的更多相关文章
- CUDA编程模型
1. 典型的CUDA编程包括五个步骤: 分配GPU内存 从CPU内存中拷贝数据到GPU内存中 调用CUDA内核函数来完成指定的任务 将数据从GPU内存中拷贝回CPU内存中 释放GPU内存 *2. 数据 ...
- CUDA编程模型之内存管理
CUDA编程模型假设系统是由一个主机和一个设备组成的,而且各自拥有独立的内存. 主机:CPU及其内存(主机内存),主机内存中的变量名以h_为前缀,主机代码按照ANSI C标准进行编写 设备:GPU及其 ...
- CUDA刷新:GPU计算生态系统
CUDA刷新:GPU计算生态系统 CUDA Refresher: The GPU Computing Ecosystem 这是CUDA Refresher系列的第三篇文章,其目标是刷新CUDA中的关键 ...
- 【并行计算-CUDA开发】CUDA存储器模型
CUDA存储器模型 除了执行模型以外,CUDA也规定了存储器模型(如图2所示)和一系列用于主控CPU与GPU间通信的不同地址空间.图中红色的区域表示GPU片内的高速存储器,橙色区域表示DRAM中的的地 ...
- CUDA 8混合精度编程
CUDA 8混合精度编程 Mixed-Precision Programming with CUDA 8 论文地址:https://devblogs.nvidia.com/mixed-precisio ...
- 第3章 窗口与消息_3.1Windows编程模型
第3章窗口与消息 3.1 Windows_编程模型 (1)窗口程序的运行过程 ①设计窗口 ②注册窗口类(RegisterClassEx).在注册之前,要先填写RegisterClassEx的参 ...
- 并行计算基础&编程模型与工具
在当前计算机应用中,对快速并行计算的需求是广泛的,归纳起来,主要有三种类型的应用需求: 计算密集(Computer-Intensive)型应用,如大型科学project计算与数值模拟: 数据密集(Da ...
- 老李分享: 并行计算基础&编程模型与工具 2
2.并行编程模型和工具 – MPI – MPI(Message Passing Interface)是一种消息传递编程模型,服务于进程通信.它不特指某一个对它的实现,而是一种标准和规范的代表,它是一种 ...
- 老李分享: 并行计算基础&编程模型与工具
在当前计算机应用中,对高速并行计算的需求是广泛的,归纳起来,主要有三种类型的应用需求: 计算密集(Computer-Intensive)型应用,如大型科学工程计算与数值模拟: 数据密集(Data-In ...
随机推荐
- hdu1316 大数
题意: 给你一个区间,问这个区间有多少个斐波那契数. 思路: 水的大数,可以直接模拟,要是懒可以用JAVA,我模拟的,打表打到1000个就足够用了... #include<s ...
- POJ2669不错的最大流 竞赛问题(枚举King的个数)
题意: 有n个人,任意两个人都比一次赛(一共比了n*(n-1)/2场),赢一场得到一分,最后的时候如果得分最高,或者是自己打败了所有比自己得分都高的人就算是King,给你每个人的最后得分, ...
- POJ1486模拟或者匈牙利变种
题意: 有n个矩形,每个矩形上的某个位置上都有一个点,但是由于矩形是透明的,当一些矩形重叠在一起的时候就很可能分不清哪个点是那个矩形的,给你n个矩形的坐标,还有n个点的坐标,然后让你找出所 ...
- nodejs-Stream(流)
Node.js Stream(流) 描述++++++++++++++++++++++++++++++++++++++++++++++++++++ Stream 是一个抽象接口,Node 中有很多对象实 ...
- 接口测试原理及Postman详解
接口测试定义 接口是前后端沟通的桥梁,是数据传输的通道,包括外部接口.内部接口.内部接口又包括:上层服务与下层服务接口,同级接口 生活中常见接口:电脑上的键盘.USB接口,电梯按钮,KFC下单 接口测 ...
- 【Docker】5. 常用命令—镜像命令
学习命令,官方文档千万别忘记了,不会的就到这里来查. 一.帮助命令 1.显示docker哪些命令 docker --help 另外,也可以查看具体命令的用法,比如我想知道命令docker images ...
- MySQL权限管理实战
前言: 不清楚各位同学对数据库用户权限管理是否了解,作为一名 DBA ,用户权限管理是绕不开的一项工作内容.特别是生产库,数据库用户权限更应该规范管理.本篇文章将会介绍下 MySQL 用户权限管理相关 ...
- Redis学习笔记六:持久化实验(AOF,RDB)
作者:Grey 原文地址:Redis学习笔记六:持久化实验(AOF,RDB) Redis几种持久化方案介绍和对比 AOF方式:https://blog.csdn.net/ctwctw/article/ ...
- Mac 无密码 SSH 登录服务器
Mac 无密码 SSH 登录服务器,只需要简单三步,不再需要记住账号密码,快速进入服务器 第一步,生成密钥对 在当前用户下创建.ssh目录 mkdir ~/.ssh 使用命令ssh-keygen生成密 ...
- ArrayList方法源码分析
本文将从ArrayList类的存储结构.初始化.增删数据.扩容处理以及元素迭代等几个方面,分析该类常用方法的源码. 数据存储设计 该类用一个Object类型的数组存储容器的元素.对于容量为空的情况,提 ...