《CUDA C++ Programming Guide》第二章 CUDA 编程模型概述

news2024/9/24 7:25:09

2.1 内核
CUDA C++ 通过允许程序员定义称为kernelC++ 函数来扩展 C++,当调用内核时,由 N 个不同的 CUDA 线程并行执行 N 次,而不是像常规 C++ 函数那样只执行一次。

使用 __global__ 声明说明符定义内核,并使用新的 <<<...>>> 执行配置语法指定内核调用的 CUDA 线程数。 每个执行内核的线程都有一个唯一的线程 ID,可以通过内置变量在内核中访问。

作为说明,以下示例代码使用内置变量 threadIdx 将两个大小为 N 的向量 AB 相加,并将结果存储到向量 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
    VecAdd<<<1, N>>>(A, B, C);
    ...
}

这里,执行 VecAdd() 的 N 个线程中的每一个线程都会执行一个加法。

2.2 线程层次
为方便起见,threadIdx 是一个 3 分量向量,因此可以使用一维、二维或三维的线程索引来识别线程,形成一个一维、二维或三维的线程块,称为block。 这提供了一种跨域的元素(例如向量、矩阵或体积)调用计算的方法。

线程的索引和它的线程 ID 以一种直接的方式相互关联:对于一维块,它们是相同的; 对于大小为(Dx, Dy)的二维块,索引为(x, y)的线程的线程ID(x + y*Dx); 对于大小为 (Dx, Dy, Dz) 的三维块,索引为 (x, y, z) 的线程的线程 ID(x + y*Dx + z*Dx*Dy)

例如,下面的代码将两个大小为NxN的矩阵AB相加,并将结果存储到矩阵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()
{
    ...
    // Kernel invocation with one block of N * N * 1 threads
    int numBlocks = 1;
    dim3 threadsPerBlock(N, N);
    MatAdd<<<numBlocks, threadsPerBlock>>>(A, B, C);
    ...
}

每个块的线程数量是有限制的,因为一个块的所有线程都应该驻留在同一个处理器核心上,并且必须共享该核心有限的内存资源。在当前的gpu上,一个线程块可能包含多达1024个线程。

但是,一个内核可以由多个形状相同的线程块执行,因此线程总数等于每个块的线程数乘以块数。

块被组织成一维、二维或三维的线程块网格(grid),如下图所示。网格中的线程块数量通常由正在处理的数据的大小决定,通常超过系统中的处理器数量。
在这里插入图片描述

<<<...>>> 语法中指定的每个块的线程数和每个网格的块数可以是 intdim3 类型。如上例所示,可以指定二维块或网格。

网格中的每个块都可以由一个一维、二维或三维的惟一索引标识,该索引可以通过内置的blockIdx变量在内核中访问。线程块的维度可以通过内置的blockDim变量在内核中访问。

扩展前面的MatAdd()示例来处理多个块,代码如下所示。

// Kernel definition
__global__ void MatAdd(float A[N][N], float B[N][N],
float C[N][N])
{
    int i = blockIdx.x * blockDim.x + threadIdx.x;
    int j = blockIdx.y * blockDim.y + threadIdx.y;
    if (i < N && j < N)
        C[i][j] = A[i][j] + B[i][j];
}

int main()
{
    ...
    // Kernel invocation
    dim3 threadsPerBlock(16, 16);
    dim3 numBlocks(N / threadsPerBlock.x, N / threadsPerBlock.y);
    MatAdd<<<numBlocks, threadsPerBlock>>>(A, B, C);
    ...
}

线程块大小为16×16(256个线程),尽管在本例中是任意更改的,但这是一种常见的选择。网格是用足够的块创建的,这样每个矩阵元素就有一个线程来处理。为简单起见,本例假设每个维度中每个网格的线程数可以被该维度中每个块的线程数整除,尽管事实并非如此。

程块需要独立执行:必须可以以任何顺序执行它们,并行或串行。 这种独立性要求允许跨任意数量的内核以任意顺序调度线程块,如下图所示,使程序员能够编写随内核数量扩展的代码。
在这里插入图片描述

块内的线程可以通过一些共享内存共享数据并通过同步它们的执行来协调内存访问来进行协作。 更准确地说,可以通过调用 __syncthreads() 内部函数来指定内核中的同步点; __syncthreads() 充当屏障,块中的所有线程必须等待,然后才能继续。 Shared Memory 给出了一个使用共享内存的例子。 除了 __syncthreads() 之外,Cooperative Groups API 还提供了一组丰富的线程同步示例。

为了高效协作,共享内存是每个处理器内核附近的低延迟内存(很像 L1 缓存),并且 __syncthreads() 是轻量级的。

2.3 存储单元层次
CUDA 线程可以在执行期间从多个内存空间访问数据,如下图所示。每个线程都有私有的本地内存。 每个线程块都具有对该块的所有线程可见的共享内存,并且具有与该块相同的生命周期。 所有线程都可以访问相同的全局内存。

在这里插入图片描述

还有两个额外的只读内存空间可供所有线程访问:常量和纹理内存空间。 全局、常量和纹理内存空间针对不同的内存使用进行了优化。 纹理内存还为某些特定数据格式提供不同的寻址模式以及数据过滤。

全局、常量和纹理内存空间在同一应用程序的内核启动中是持久的。

2.4 异构编程
如下图所示,CUDA 编程模型假定 CUDA 线程在物理独立的设备上执行,该设备作为运行 C++ 程序的主机的协处理器运行。例如,当内核在 GPU 上执行而 C++ 程序的其余部分在 CPU 上执行时,就是这种情况。
在这里插入图片描述

CUDA 编程模型还假设主机(host)和设备(device)都在 DRAM 中维护自己独立的内存空间,分别称为主机内存和设备内存。因此,程序通过调用 CUDA 运行时(在编程接口中描述)来管理内核可见的全局、常量和纹理内存空间。这包括设备内存分配和释放以及主机和设备内存之间的数据传输。

统一内存提供托管内存来桥接主机和设备内存空间。托管内存可从系统中的所有 CPU 和 GPU 访问,作为具有公共地址空间的单个连贯内存映像。此功能可实现设备内存的超额订阅,并且无需在主机和设备上显式镜像数据,从而大大简化了移植应用程序的任务。

:串行代码在主机(host)上执行,并行代码在设备(device)上执行。

2.5 异步SIMT编程模型
在 CUDA 编程模型中,线程是进行计算或内存操作的最低抽象级别。 从基于 NVIDIA Ampere GPU 架构的设备开始,CUDA 编程模型通过异步编程模型为内存操作提供加速。 异步编程模型定义了与 CUDA 线程相关的异步操作的行为。

异步编程模型为 CUDA 线程之间的同步定义了异步屏障的行为。 该模型还解释并定义了如何使用 cuda::memcpy_asyncGPU计算时从全局内存中异步移动数据。

2.5.1 异步操作
异步操作定义为由CUDA线程发起的操作,并且与其他线程一样异步执行。在结构良好的程序中,一个或多个CUDA线程与异步操作同步。发起异步操作的CUDA线程不需要在同步线程中.

这样的异步线程(as-if 线程)总是与发起异步操作的 CUDA 线程相关联。异步操作使用同步对象来同步操作的完成。这样的同步对象可以由用户显式管理(例如,cuda::memcpy_async)或在库中隐式管理(例如,cooperative_groups::memcpy_async)。

同步对象可以是 cuda::barriercuda::pipeline。这些对象在Asynchronous BarrierAsynchronous Data Copies using cuda::pipeline.中进行了详细说明。这些同步对象可以在不同的线程范围内使用。作用域定义了一组线程,这些线程可以使用同步对象与异步操作进行同步。下表定义了CUDA c++中可用的线程作用域,以及可以与每个线程同步的线程。

在这里插入图片描述

这些线程作用域是在CUDA标准c++库中作为标准c++的扩展实现的。

2.6 Compute Capability
设备的Compute Capability由版本号表示,有时也称其“SM版本”。该版本号标识GPU硬件支持的特性,并由应用程序在运行时使用,以确定当前GPU上可用的硬件特性和指令。

Compute Capability包括一个主要版本号X和一个次要版本号Y,用X.Y表示

主版本号相同的设备具有相同的核心架构。设备的主要修订号是8,为NVIDIA Ampere GPU的体系结构的基础上,7基于Volta设备架构,6设备基于Pascal架构,5设备基于Maxwell架构,3基于Kepler架构的设备,2设备基于Fermi架构,1是基于Tesla架构的设备。

次要修订号对应于对核心架构的增量改进,可能包括新特性。

Turing是计算能力7.5的设备架构(sm75),是基于Volta架构的增量更新。

CUDA-Enabled GPUs 列出了所有支持 CUDA 的设备及其计算能力。Compute Capabilities给出了每个计算能力的技术规格。

注意:特定GPU的计算能力版本不应与CUDA版本(如CUDA 7.5、CUDA 8、CUDA 9)混淆,CUDA版本指的是CUDA软件平台的版本CUDA平台被应用开发人员用来创建运行在许多代GPU架构上的应用程序,包括未来尚未发明的GPU架构。尽管CUDA平台的新版本通常会通过支持新的GPU架构的计算能力版本来增加对该架构的本地支持,但CUDA平台的新版本通常也会包含软件功能。
CUDA 7.0CUDA 9.0开始,不再支持TeslaFermi架构。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/854709.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

CTF PWN之精确覆盖变量数据

刚开始接触pwn的朋友在做pwn练习时可能会有这样的疑问&#xff0c;怎么做到精确覆盖变量数据呢&#xff1f; 我们做pwn练习之前需要先知道&#xff1a;命令行参数C语言的main函数拥有两个参数&#xff0c;为int类型的argc参数&#xff0c;以及char**类型argv参数。其中argc参数…

进入现代云技术的世界-APIGateway、ServiceMesh、OpenStack、异步化框架、云原生框架、命令式API与声明式API

目录 APIGateway Service Mesh OpenStack 异步化框架 云原生框架 命令式API与声明式API APIGateway API网关&#xff08;API Gateway&#xff09;是一个服务器——充当了客户端和内部服务之间的中间层。API网关负责处理API请求&#xff0c;将客户端的请求路由到相应的后端…

centos8.5本地yum源报错

在下载文件出现以下错误 [rootserver ~]# yum install gcc Updating Subscription Management repositories. Unable to read consumer identity This system is not registered with an entitlement server. You can use subscription-manager to register. RHEL8.5-BaseOS …

上海亚商投顾:沪指录得4连阴 N盟固利盘中最高涨近37倍

上海亚商投顾前言&#xff1a;无惧大盘涨跌&#xff0c;解密龙虎榜资金&#xff0c;跟踪一线游资和机构资金动向&#xff0c;识别短期热点和强势个股。 市场情绪 沪指今日延续调整走势&#xff0c;科创50指数跌超1%&#xff0c;创业板指则较为抗跌。医药医疗股集体爆发&#xf…

【网络基础实战之路】实现RIP协议与OSPF协议间路由交流的实战详解

系列文章传送门&#xff1a; 【网络基础实战之路】设计网络划分的实战详解 【网络基础实战之路】一文弄懂TCP的三次握手与四次断开 【网络基础实战之路】基于MGRE多点协议的实战详解 【网络基础实战之路】基于OSPF协议建立两个MGRE网络的实验详解 PS&#xff1a;本要求基于…

Pytorch深度学习-----神经网络模型的保存与加载(VGG16模型)

系列文章目录 PyTorch深度学习——Anaconda和PyTorch安装 Pytorch深度学习-----数据模块Dataset类 Pytorch深度学习------TensorBoard的使用 Pytorch深度学习------Torchvision中Transforms的使用&#xff08;ToTensor&#xff0c;Normalize&#xff0c;Resize &#xff0c;Co…

前端先行模拟接口(mock+expres+json)

目录 mock模拟数据&#xff1a;data/static.js 路由&#xff1a;index.js 服务器&#xff1a;server.js yarn /node 启动服务器&#xff1a;yarn start 客户端&#xff1a;修改代理路径(修改设置后都要重启才生效) 示例 后端框架express构建服务器 前端发起请求 静态数…

Power BI中实现购物篮分析详解

一、购物篮分析简介 相信&#xff0c;很多人都听过沃尔玛购物篮分析的故事---“啤酒和尿布湿“&#xff0c;即分析购买尿布湿的顾客最喜欢购买的商品是什么&#xff1f;&#xff08;啤酒&#xff09;。在零售终端经营中&#xff0c;通过购物篮分析&#xff0c;分析不同商品之间…

Leetcode-每日一题【剑指 Offer 16. 数值的整数次方】

题目 实现 pow(x, n) &#xff0c;即计算 x 的 n 次幂函数&#xff08;即&#xff0c;xn&#xff09;。不得使用库函数&#xff0c;同时不需要考虑大数问题。 示例 1&#xff1a; 输入&#xff1a;x 2.00000, n 10输出&#xff1a;1024.00000 示例 2&#xff1a; 输入&#…

数据挖掘全流程解析

数据挖掘全流程解析 数据指标选择 在这一阶段&#xff0c;使用直方图和柱状图的方式对数据进行分析&#xff0c;观察什么数据属性对于因变量会产生更加明显的结果。 如何绘制直方图和条形统计图 数据清洗 观察数据是否存在数据缺失或者离群点的情况。 数据异常的两种情况…

每日后端面试5题 第三天

1. 线程有哪几种状态以及各种状态之间的转换&#xff1f;(必会) 看图&#xff1a; 图片来自 线程状态转换图及其5种状态切换_小曹的blog的博客-CSDN博客 图片来自 总算把线程六种状态的转换说清楚了&#xff01; - 知乎 线程一共有4种状态&#xff0c;分别是&#xff1a; 1.…

js手写贪吃蛇游戏

前端手写贪吃蛇游戏 贪吃蛇游戏 场景 使用了js 和 html /css 就可以完成 一个贪吃蛇小游戏 技术分析 主要用到的几个技术点&#xff1a; clientWidth &#xff1a;元素的宽度&#xff0c;包含内边距clientHeight &#xff1a;元素的高度&#xff0c;包含内边距setInterval&am…

【论文笔记】Cross Modal Transformer: Towards Fast and Robust 3D Object Detection

原文链接&#xff1a;https://arxiv.org/abs/2301.01283 1. 引言 受到DETR启发&#xff0c;本文提出鲁棒的端到端多模态3D目标检测方法CMT&#xff08;跨模态Transformer&#xff09;。首先使用坐标编码模块&#xff08;CEM&#xff09;&#xff0c;通过将3D点集隐式地编码为多…

面试笔记:Android 架构岗,一次4小时4面的体验

作者&#xff1a;橘子树 此次面试一共4面4小时&#xff0c;中间只有几分钟间隔。对持续的面试状态考验还是蛮大的。 关于面试的心态&#xff0c;保持悲观的乐观主义心态比较好。面前做面试准备时保持悲观&#xff0c;尽可能的做足准备。面后积极做复盘&#xff0c;乐观的接受最…

[分享]STM32G070 串口 乱码 解决方法

硬件 NUCLEO-G070RB 工具 cubemx 解决方法 7bit 改为 8bit printf 配置方法 添加头文件 #include <stdio.h> 添加重定向代码 #ifdef __GNUC__#define PUTCHAR_PROTOTYPE int __io_putchar(int ch)#else#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)#endi…

安装程序报错问题解决 -2147287037 <<30005>> 2203

本文如下报错适用&#xff1a; 一、The installer has encountered an unexpected error installing this package. Thismay indicate a problem with this package. The error code is 2203 二、错误 2203.数据库&#xff1a; C:\WINDOWS\Installer\inprogressinstallinfo.i…

别找了,这7个AI绘画图软件够你用了!

AI 绘图工具最妙的是也让人人都能成为朋友圈里的“画家”&#xff0c;如果你也想要拥有一个趁手的 AI 绘画工具&#xff0c;那么就跟随本文一起来看看吧&#xff01;本文精选了7全球顶尖的AI绘图工具给大家&#xff0c;包括&#xff1a;即时灵感、Jasper Art、Images.ai、Night…

休闲卤味强势崛起:卤味零食成为新一代热门美食

随着人们生活水平的提高和消费观念的转变&#xff0c;休闲卤味逐渐成为了人们日常生活中的热门美食。据最新数据显示&#xff0c;2022年&#xff0c;我国卤味市场销售额达到了约2000亿元&#xff0c;预计到2025年将突破3000亿元大关。其中&#xff0c;休闲卤味以每年10%的速度持…

趋势洞察:中国企业高质量出海白皮书!

目前&#xff0c;我国仍处于战略发展机遇期的大背景&#xff0c; 面对全球经济放缓、不确定性增强的常态&#xff0c;国内高端市场的竞争也日趋激烈&#xff0c;对于寻求高质量发展的中国企业&#xff0c; 出海将成为重要的增长点。 今天运营坛为大家整理了一份《中国企业高质量…

弹簧阻尼系统前馈PID位置控制(PLC完整闭环仿真SCL+ST代码)

弹簧阻尼系统的前馈PID控制请参看下面文章链接: 前馈控制之如何计算前馈量(质量弹簧阻尼系统)_前馈控制量_RXXW_Dor的博客-CSDN博客带前馈控制的博途PID程序请参看下面的文章链接:首先我们看下什么是弹簧阻尼系统。1、质量弹簧阻尼模型。_前馈控制量https://rxxw-control.bl…