CUDA的编程模式

        本章介绍了CUDA编程模型背后的主要概念,概述了它们在C++中是如何公开的。在编程接口中对CUDA C++进行了详细的描述。

        本章和下一章中使用的矢量加法示例的完整代码可以在矢量加法CUDA示例中找到。

2.1、内核

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

        内核是使用__global__声明说明符定义的,并且为给定内核调用执行该内核的CUDA线程数是使用新的<<…>>指定的执行配置语法(请参阅C++语言扩展)。执行内核的每个线程都有一个唯一的线程ID,可以通过内置变量在内核中访问该ID。如图所示,以下示例代码使用内置变量threadIdx,将大小为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 threadsVecAdd<<<1, N>>>(A, B, C);...
}

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

2.2、线程层次结构

        为了方便起见,threadIdx是一个3个组件的向量,这样线程可以使用一维、二维或三维线程索引进行标识,形成一维、二维或三维线程块,称为线程块。这为在向量、矩阵或体积等域上执行计算提供了一种自然的方式。

        线程的索引和其线程ID之间的关系非常简单:对于一维块,它们是相同的;对于大小为(Dx, Dy)的二维块,线程索引为(x, y)的线程的线程ID是(x + y Dx);对于大小为(Dx, Dy, Dz)的三维块,线程索引为(x, y, z)的线程的线程ID是(x + y Dx + z Dx Dy)。

        作为一个例子,以下代码将两个大小为NxN的矩阵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()
{...// Kernel invocation with one block of N * N * 1 threadsint numBlocks = 1;dim3 threadsPerBlock(N, N);MatAdd<<<numBlocks, threadsPerBlock>>>(A, B, C);...
}

        每个块中的线程数量是有限的,因为一个块的所有线程都预期驻留在同一个处理器核心上,并且必须共享该核心的有限内存资源。在当前的GPU上,一个线程块可能包含多达1024个线程。然而,一个内核可以由多个形状相同的线程块执行,因此总线程数等于每个线程块中的线程数乘以线程块数。

        块组织成1D、2D或3D的线程块网格,如图6所示。网格中的线程块数量通常由正在处理的数据的大小决定,这通常超过系统中的处理器数量。

 

图6 螺纹块网格图6螺纹块网格

        <<<…>>中指定的每个块的线程数和每个网格的块数语法可以是int或dim3类型。二维块或网格可以如上面的示例中那样指定。网格中的每个块都可以通过一个一维、二维或三维的唯一索引来识别,该索引可通过内置的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 invocationdim3 threadsPerBlock(16, 16);dim3 numBlocks(N / threadsPerBlock.x, N / threadsPerBlock.y);MatAdd<<<numBlocks, threadsPerBlock>>>(A, B, C);...
}

        16x16(256个线程)的线程块大小虽然在这种情况下是任意的,但却是常见的选择。网格是用足够的块创建的,与以前一样,每个矩阵元素有一个线程。为了简单起见,本示例假设每个维度中每个网格的线程数可以被该维度中每个块的线程数整除,但事实并非如此。

        线程块需要独立执行:必须能够以任何顺序、并行或串行执行。如图5所示,这种独立性要求允许在任何数量的内核上以任何顺序调度线程块,使程序员能够编写随内核数量而扩展的代码。

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

        为了高效协作,共享内存应该是每个处理器核心附近的低延迟内存(很像一级缓存),_syncthreads()应该是轻量级的。 

2.3、内存层次

        CUDA线程在执行过程中可以访问来自多个内存空间的数据,如图7所示。每个线程都有专用的本地内存。每个线程块都共享对该块的所有线程可见的内存,并且与该块具有相同的生存期。

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

2.4、异构编程

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

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

        统一内存提供托管内存以桥接主机和设备内存空间。托管内存可以从系统中的所有CPU和GPU访问,作为一个具有公共地址空间的统一内存映像。此功能实现了对设备内存的订阅,并通过消除在主机和设备上显式镜像数据的需要,大大简化了分配应用程序的任务。

串行代码在主机上执行,而并行代码在设备上执行。 

2.5、计算能力

        设备的计算能力由版本号表示,有时也称为“SM版本”。此版本号标识GPU硬件支持的功能,并由应用程序在运行时用于确定当前GPU上可用的硬件功能和/或指令。计算能力包括主要修订号X和次要修订号Y,并由X.Y表示。

        具有相同主要修订号的设备具有相同的核心体系结构。主要修订号是基于Volta架构的设备7,基于Pascal架构的设备6,基于Maxwell架构的设备5,基于Kepler架构的设备3,基于Fermi架构的设备2,以及基于Tesla架构的设备1。

        次要修订号对应于对核心体系结构的增量改进,可能包括新功能。图灵是计算能力为7.5的设备的架构,是基于Volta架构的增量更新。

        CUDA Enabled GPU列出了所有CUDA Enabled设备及其计算能力。计算能力给出了每种计算能力的技术规范。

        特定GPU的计算能力版本不应与CUDA版本(例如,CUDA 7.5、CUDA 8、CUDA 9)混淆,CUDA版本是CUDA软件平台的版本。CUDA平台被应用程序开发人员用来创建在许多代GPU架构上运行的应用程序,包括尚未发明的未来GPU架构。虽然CUDA平台的新版本通常通过支持新GPU架构的计算能力版本来增加对该架构的本地支持,但CUDA平台新版本通常还包括独立于硬件生成的软件功能。

        分别从CUDA 7.0和CUDA 9.0开始,不再支持特斯拉和费米体系结构。

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

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

相关文章

MS-DETR论文解读

文章目录 前言一、摘要二、引言三、贡献四、MS-DETR模型方法1、模型整体结构解读2、模型改善结构解读3、一对多监督原理 五、实验结果1、实验比较2、论文链接 总结 前言 今天&#xff0c;偶然看到MS-DETR论文&#xff0c;以为又有什么高逼格论文诞生了。于是&#xff0c;我想查…

PandoraNext—一个让你呼吸顺畅的ChatGPT

博客地址 PandoraNext—一个让你呼吸顺畅的ChatGPT-雪饼 (xue6ing.cn)https://xue6ing.cn/archives/pandora--yi-ge-rang-ni-hu-xi-shun-chang-de-chatgpt 项目 项目地址 pandora-next/deploy 项目介绍 支持多种登录方式&#xff1a; 账号/密码 Access Token Session To…

【大数据OLAP引擎】StartRocks存算分离

存算分离的原因 降低存储成本&#xff1a;同样的存储大小对象存储价格只有SSD的1/10&#xff0c;所以号称存储成本降低80%不是吹的。 存算一体到存算分离 存算一体 作为 MPP 数据库的典型代表&#xff0c;StarRocks 3.0 版本之前使用存算一体 (shared-nothing) 架构&#xf…

Oracle regexp_substr

select regexp_substr(123|456|789, [^|], 1, 2) from dual;

软件测试|快速、可靠的JavaScript依赖管理工具——yarn

简介 Yarn是一个由Facebook于2016年推出的JavaScript软件包管理器。它的目标是解决npm&#xff08;Node.js的默认软件包管理器&#xff09;在性能和可靠性方面的一些问题。Yarn旨在提供更快、更安全、更稳定的依赖项安装过程&#xff0c;使JavaScript开发人员能够更轻松地管理…

TortoiseSVN·文件锁定与清理

安装 TortoiseSVN 的时候&#xff0c;选择 svn 命令可用, 选择 will be intalled on local hard drive 。 在锁定的文件夹内 cmd 进入终端&#xff0c;输入 find . -type f -name ".svn/lock" -exec rm -f {} \; 删除所有锁定文件。进行清理操作&#xff1a;svn clea…

RHCE9学习指南 第18章 日志

日志中记录了各种各样的问题&#xff0c;所以读取日志是检测并排除故障的一个重要方式&#xff0c;日志文件默认放在/var/log/目录下。不同的问题要读取不同的日志&#xff0c;例如&#xff0c;邮件发不出去&#xff0c;可以读取日志文件件/var/log/maillog&#xff1b;要查看哪…

【38 Pandas+Pyecharts | 奥迪汽车销量数据分析可视化】

文章目录 &#x1f3f3;️‍&#x1f308; 1. 导入模块&#x1f3f3;️‍&#x1f308; 2. Pandas数据处理2.1 读取数据2.2 查看数据信息2.3 数据处理 &#x1f3f3;️‍&#x1f308; 3. Pyecharts数据可视化3.1 奥迪用户购车时间分布3.2 奥迪各系销量占比饼图3.3 奥迪各系销量…

外汇天眼:CQG 与 TradeStation Securities 的经纪服务集成

TradeStation Securities, Inc.&#xff0c;一家自营的在线股票、ETF、期权和期货交易经纪公司&#xff0c;宣布与CQG合作&#xff0c;CQG是一家为交易员、经纪商、商业套保者和交易所提供高性能技术解决方案的全球供应商&#xff0c;已与TradeStation Securities的经纪服务集成…

Zustand 状态管理

Zustand 状态管理 安装创建 Store给 Store 添加TS类型约束在页面使用 Store返回 Store 中所有状态在 Store 中使用 async 异步方法使用 Immer Middleware (中间件) 更新深层嵌套的 State使用 get 方法&#xff0c;在 set 方法外访问 State 中的数据使用 selector什么是 selecto…

GNN如何处理表格?

链接: https://ieeexplore.ieee.org/document/10184514 在这篇综述中&#xff0c;我们深入探讨了使用图神经网络&#xff08;GNNs&#xff09;进行表格数据学习&#xff08;TDL&#xff09;的领域&#xff0c;这是一个深度学习方法在分类和回归任务中相比传统方法表现出越来越…

Unity中BRP下的深度图

文章目录 前言一、在Shader中使用1、在使用深度图前申明2、在片元着色器中 二、在C#脚本中开启摄像机深度图三、最终效果 前言 在之前的文章中&#xff0c;我们实现了URP下的深度图使用。 Unity中URP下使用屏幕坐标采样深度图 在这篇文章中&#xff0c;我们来看一下BRP下深度…

2024-01-03 无重叠区间

435. 无重叠区间 思路&#xff1a;和最少数量引爆气球的箭的思路基本都是一致了&#xff01;贪心就是比较左边的值是否大于下一个右边的值 class Solution:def eraseOverlapIntervals(self, points: List[List[int]]) -> int:points.sort(keylambda x: (x[0], x[1]))# 比较…

2023-12-30 买卖股票的最佳时机 II和跳跃游戏以及跳跃游戏 II

122. 买卖股票的最佳时机 II 思路&#xff1a;关键点是每一次利用峰值来计算【画图好理解一点&#xff0c;就是计算陡坡的值】&#xff01;每一次累加和的最大! 或者可以这样理解&#xff0c;把利润划分为每天的&#xff0c;如假如第 0 天买入&#xff0c;第 3 天卖出&#xf…

ELF文件格式解析二

使用objdump命令查看elf文件 objdump -x 查看elf文件所有头部的信息 所有的elf文件。 程序头部&#xff08;Program Header&#xff09;中&#xff0c;都以 PT_PHDR和PT_INTERP先开始。这两个段必须在所有可加载段项目的前面。 从上图中的INTERP段中&#xff0c;可以看到改段…

《GreenPlum系列》GreenPlum详细入门教程02-GreenPlum安装

文章目录 第二章 GreenPlum安装1.Docker创建centos容器1.1 拉取centos7镜像1.2 创建容器1.3 进入容器1.4 容器和服务器免密操作1.4.1 生成密钥1.4.2 拷贝密钥 1.5 安装ssh服务和网络必须应用1.6 容器设置root密码1.6.1 安装passwd应用1.6.2 容器本机root设置密码 1.7 容器本机免…

uniapp获取手机当前信息及应用版本

appVersion 是app端查询的数据信息 appWgtVersion 是浏览器端查询的数据信息 onLoad() {const systemInfo uni.getSystemInfoSync();console.log(systemInfo);// #ifdef H5const uniAppVersion systemInfo.appVersion;// #endif// #ifndef H5const uniAppVersion systemIn…

C++学习笔记——对象的指针

目录 一、对象的指针 二、减少对象的复制开销 三、应用案例 游戏引擎 图像处理库 数据库管理系统 航空航天软件 金融交易系统 四、代码的案例应用 一、对象的指针 是一种常用的技术&#xff0c;用于处理对象的动态分配和管理。使用对象的指针可以实现以下几个方面的功…

无法访问Bing网站 - 解决方案

问题 Bing官方网址&#xff1a;https://www.bing.com/ 电脑无法访问Bing网站&#xff0c;但手机等移动设备可以访问Bing网站&#xff0c;此时可尝试以下方案。 以下方案适用于各种系统&#xff0c;如Win/Linux系统。 解决方案 方案1 修改Bing网址为&#xff1a;https://www4…

JAVA毕业设计632—基于Java+ssm的宠物店商城系统(源代码+数据库)

毕设所有选题&#xff1a; https://blog.csdn.net/2303_76227485/article/details/131104075 基于Javassm的宠物店商城系统(源代码数据库)632 一、系统介绍 本项目分为用户、营养师、管理员三种角色 1、用户&#xff1a; 登录、注册、宠物信息、宠物粮食、宠物用品、宠物疫…