GPU硬件结构和编程模型(源于nvidia的CUDA文档)

article/2025/9/1 22:14:58

GPU的硬件结构

GPU通过一个可扩展的多线程流式多处理器(SMs)构建。一个multiprocessor可以在同一时间处理上百个线程。为了管理这些线程,使用一个特殊的结构SIMT。利用单线程中指令级的并行,以及同步硬件多线程实现的广泛线程级并行性。

SIMT Architecture

warps:32个并行线程组。

组成warps的独立线程在同一个程序地址同时启动,但是他们分别由各自的指令地址计数器和寄存器状态,也因此可以自由的分支和独立执行。意思是,half-warp在一个warp中可以是前一个也可以是后一个。

当multiprocessor给了一个或者多个线程块去执行时,它会将块分成warps,为了执行,每一个warps都可以被warps调度器(warps scheduled)调度。划分warps 的方式是相同,每一个warp中包含一组连续的线程,这些线程我们可以通过线程ID获取,从第一个包含线程ID为0的warps开始,线程ID递增。

在同一时刻,一个warp执行一个共同的指令。当warp中的线程都在同一个执行路径时,效率会完全展现,但是如果warp中的线程因为不同的数据依赖而不得已出现分支,warp会执行每一条分支,但是会禁用不在这条执行路径上的线程。这种分支发散的情况仅仅出现在warp中。注意,不同的warp可以独立执行,不管它们执行的是否是同一个代码指令。

因为SIMT可以指定单个线程的发散和执行,程序员可以写出一个独立的,可以扩展的以及协作线程数据并行的线程级代码。通过独立的线程调度,GPU维护每个线程的执行状态,包括程序计数器和调用堆栈,并可以以每个线程的粒度产生执行,以更好地利用执行资源或允许一个线程等待另一个线程生成数据。调度优化器来确定如何将来自同一个warp的线程组织到SIMT单元中。

Hardware Multithreading

在warp的整个生命周期内,多处理器处理的每个warp的执行上下文(程序计数器、寄存器等)都在芯片上维护。因此,从一个执行上下文切换到另一个执行上下文是没有代价的,并且在每个指令发出时,warp调度器都会选择一个具有准备好执行其下一条指令的线程(warp的活动线程)的warp,并向这些线程发出指令。

对于给定内核,可以驻留在多处理器上并一起处理的块和扭曲的数量取决于内核使用的寄存器和共享内存的数量以及多处理器上可用的寄存器和共享内存的数量。如果multiprocessor没有足够的寄存器或共享内存来处理至少一个块,内核将无法启动。

一个block中warp的数量如下:
c e i l ( T W s i z e , 1 ) ceil(\frac{T}{W_{size}},1) ceil(WsizeT,1)
T是block中的线程数量

W_size是warp的大小,这里等于32

Programmer Model

Kernel

CUDA C++ 可以通过核函数扩展到C++。当它被调用时,它被N个不同的CUDA线程执行N次。使用特殊的声明符号__global__定义各一个核函数,CUDA线程的数量在核函数调用时使用<<<…>>>运算符配置。每一个执行核函数的CUDA线程都有不同的线程ID。

下面有一个例子,将两个大小为N的vector相加,加过放在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(),完成一对元素相加的任务。

Thread Hierarchy (线程等级)

threadIdx是一个三分量向量,因此可以使用一维、二维或三维线程索引来识别线程,形成一维、二维或三维线程块。在跨域中的元素(如向量、矩阵或体积),这提供了一种调用计算的自然方式。

线程索引和线程ID之间有一个明确的关系。对于一维线程块来说,它们是一样的。对于二维来说(Dx,Dy),线程索引(x,y)的线程ID是(x+yDx);对于三维的线程块(Dx,Dy,Dz),线程索引(x,y,z)的线程ID是(x+yDx+zDxDy)。

例子,下面代码是将两个NxN的矩阵相加

// 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);...
}

每一个线程块的数量是有限制的,因为一个块的所有线程都应该驻留在同一个处理器内核上,并且必须共享该内核的有限内存资源。在目前的GPUs中,一个线程块包含1024个线程。但是,内核可以由多个形状相同的线程块执行,因此线程总数等于每个块的线程数乘以块数。块被组织到一个线程块网格中。网格中线程块的数量通常由正在处理的数据的大小决定,该大小通常超过系统中的处理器数量。

在这里插入图片描述

每一个块中的线程数量和每一个网格中块的数量可以在<<<…>>>中用int或者dim3来配置。

更新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个线程)的线程块大小是常见的选择。网格是用足够多的块创建的,与以前一样,每个矩阵元素有一个线程。为简单起见,此示例假设每个维度中每个网格的线程数可以被该维度中每个块的线程数平均整除。

线程块是独立执行的,必须能够以任何顺序并行或串联执行它们。这种独立性要求允许线程块按任意顺序在任意数量的内核上调度,从而使程序员能够编写随内核数量扩展的代码。如图一样

在这里插入图片描述

块内的线程可以通过共享内存共享数据,并通过同步执行来协调内存访问来进行协作。共享内存应该是靠近每个处理器核心的低延迟内存。

Memory Hierarchy

CUDA线程在执行期间可以访问多个内存空间中的数据。每一个线程都有一个私有本地内存,每一个线程块都有一个块内线程都可见的共享内存,它和线程块有相同的生命周期。还有一个所有线程都可以访问的全局内存。

有两个对所有线程只读的内存空间:常量内存和texture内存。全局,常量和texture通过不同的内存使用方式优化。全局、常量和texture内存空间在同一应用程序启动的内核中是持久的。

在这里插入图片描述

Heterogeneous Programming(异构编程)

CUDA编程模型假设CUDA线程在物理上独立的设备(device)上执行,该设备作为运行C++程序的主机(host)的协处理器运行。意思就是,核函数在GPUs上执行,其余的C++程序在CPU上执行。CUDA编程模型假设主机和设备都在DRAM上维持着它们自己独立的内存空间,分别是主机内存和设备内存。因此,程序可以通过调用CUDA运行时API来管理内核中可见的全局、常量和texture内存空间。包括设备内存的分配和释放,主机与设备之间的转换。

统一内存提供托管内存(managed memory),以桥接主机和设备内存空间。可从系统中的所有CPU和GPU访问托管内存,并将其作为具有公共地址空间的单个一致内存映像进行访问,此功能可以实现设备内存的过度订阅,并且可以通过消除在主机和设备上显式镜像数据的需要,大大简化移植应用程序的任务。(Unified Memory provides managed memory to bridge the host and device memory spaces. Managed memory is accessible from all CPUs and GPUs in the system as a single, coherent memory image with a common address space. This capability enables oversubscription of device memory and can greatly simplify the task of porting applications by eliminating the need to explicitly mirror data on host and device.)。

在这里插入图片描述

Asynchronous SIMT Programming Model(异步SIMT编程模型)

在CUDA编程模型中,做计算和内存管理时,线程是最低级的抽象概念。异步编程模型定义了关于CUDA线程的异步操作行为。

Asynchronous Operations

An asynchronous operation is defined as an operation that is initiated by a CUDA thread and is executed asynchronously as-if by another thread

这样一个异步线程(as-if thread)总是与启动异步操作的CUDA线程相关联。异步操作使用同步对象同步操作的完成我一段我不太理解它在说什么,还没学到位。我把原文放在这里。

An asynchronous operation is defined as an operation that is initiated by a CUDA thread and is executed asynchronously as-if by another thread. In a well formed program one or more CUDA threads synchronize with the asynchronous operation. The CUDA thread that initiated the asynchronous operation is not required to be among the synchronizing threads.

Such an asynchronous thread (an as-if thread) is always associated with the CUDA thread that initiated the asynchronous operation. An asynchronous operation uses a synchronization object to synchronize the completion of the operation. Such a synchronization object can be explicitly managed by a user (e.g., cuda::memcpy_async) or implicitly managed within a library (e.g., cooperative_groups::memcpy_async).

A synchronization object could be a cuda::barrier or a cuda::pipeline. These objects are explained in detail in Asynchronous Barrier and Asynchronous Data Copies using cuda::pipeline. These synchronization objects can be used at different thread scopes. A scope defines the set of threads that may use the synchronization object to synchronize with the asynchronous operation. The following table defines the thread scopes available in CUDA C++ and the threads that can be synchronized with each.

Thread ScopeDescription
cuda::thread_scope::thread_scope_threadOnly the CUDA thread which initiated asynchronous operations synchronizes.
cuda::thread_scope::thread_scope_blockAll or any CUDA threads within the same thread block as the initiating thread synchronizes.
cuda::thread_scope::thread_scope_deviceAll or any CUDA threads in the same GPU device as the initiating thread synchronizes.
cuda::thread_scope::thread_scope_systemAll or any CUDA or CPU threads in the same system as the initiating thread synchronizes.

Compute Capability

设备的计算能力被表示为它的版本号,也被称为"SM version"。此版本号标识GPU硬件支持的功能,并由应用程序在运行时使用,以确定当前GPU上可用的硬件功能和/或指令。

计算能力包括主要修订号X和次要修订号Y,并用X.Y表示。相同的主修订号版本设备有相同的核心架构。主修订号为8的核心架构是NVIDA Ampere GPU,7是Volta,6是Pascal,5是Maxwell,3是Kepler,2是Fermi,1是Tesla。次要修订号对应于核心架构的增量改进,可能包括新功能。

Turing是计算能力7.5的架构,这是在Volta架构上增量式的改进。


http://chatgpt.dhexx.cn/article/eWUW1eUW.shtml

相关文章

实例分割文献阅读笔记(一)SimT

阅读 SimT: Handling Open-set Noise for Domain Adaptive Semantic Segmentation 原作者知乎文章链接&#xff1a;知乎文章 GitHub链接&#xff1a;开源数据 SimT (CVPR22)&#xff1a;为了解决域自适应&#xff08;包含UDA和SFDA&#xff09;任务中目标域数据伪标签中存在…

第三章 SIMT 内核:指令和寄存器数据流

在本章和下一章中&#xff0c;我们将研究现代 GPU 的架构和微架构。 我们将对 GPU 架构的讨论分为两部分&#xff1a;(1) 在本章中研究实现计算部分的 SIMT 内核&#xff0c;然后 (2) 在下一章中研究内存系统。 在其传统的图形渲染角色中&#xff0c;GPU 访问数据集&#xff0…

从GPU编程到SIMT核心

本文转自&#xff1a;从GPU编程到SIMT核心 - 知乎 (zhihu.com) 1、前言&本文重点 在 GPGPU 显得愈发重要的今天&#xff0c;仅凭 nVidia, AMD 提供的编程接口来了解 GPU 未免显得太单薄了些。时至今日&#xff0c; GPU 内部如何执行一条指令的对程序员来说依然是透明的、…

并行计算范式-SIMD vs SIMT vs SMT: What’s the Difference Between Parallel Processing Models?

Modern processor architectures utilize various execution models. Out of these, two are most popular: SIMD (Single Instruction Multiple Data) and SIMT (Single Instruction Multiple Threads). There’s also SMT (Simultaneous Multithreading), but that’s someth…

SIMD<SIMT<SMT: NVIDIA GPU的并行机制

原文出处&#xff1a; SIMD < SIMT < SMT: parallelism in NVIDIA GPUs 目录 1、概述 1.1、SIMD 2、SIMD vs SIMT 2.1 单指令、多套寄存器组 2.2 单指令、多个数据访问单元 2.3 单指令、多种运算逻辑路径 3、SIMD vs SIMT 3.1 GPU通过多thread来实现高thro…

关于GPU一些笔记(SIMT方面)

GPU组成 《计算机组成原理 — GPU 图形处理器》已经大概说明出GPU一般都是由比CPU多的core组成&#xff0c;而每个core 相当于一个单独线程进行计算&#xff0c;并且可以同时触发执行相同的单一指令但是每个计算单元数据不同(称之为SIMD)的指令执行。在英伟达GPU中 core一般称…

如何理解GPU中的SIMT(单指令流多线程模型)

随着设备尺寸逐渐变小&#xff0c;使得时钟频率很难有大的提升&#xff0c;人们开始寻找更有效的架构。为了提高能源效率&#xff0c;需要引入支持向量运算的硬件和减少数据的移动。 当下的架构通常是CPUGPU的&#xff0c;CPU在未来一段时间不会完全被GPU所取代&#xff0c;因…

mysql怎么设置主键唯一性约束_MySQL主键约束和唯一性约束

MySQL主键约束和唯一性约束都是索引&#xff0c;它们的区别是&#xff1a; 主键字段可以确保唯一性&#xff0c;但主键字段不能为NULL. 唯一性约束可以确保唯一性&#xff0c;但唯一性约束的字段可以为NULL 唯一性约束对含有NULL的记录不起作用&#xff0c;即可以重复加入含有N…

mysql唯一性约束的作用_sql唯一约束有什么用

SQL中唯一约束的作用是保证每个记录中都有一个唯一的标识&#xff0c;使得该列上没有相同的两个记录值&#xff1b;其中表的主键就是一个唯一性约束&#xff0c;不过主键只能有一个&#xff0c;所以如果其他列的数据不允许重复的话&#xff0c;就可以建立唯一性约束。 SQL中唯一…

mysql多字段唯一约束_mysql多字段唯一约束

MySQL唯一约束(Unique Key)要求该列唯一,允许为空,但只能出现一个空值。唯一约束可以确保一列或者几列不出现重复值。 在创建表时设置唯一约束 在定义完列之后直接使用 UNIQUE 关键字指定唯一约束,语法规则如下: UNIQUE 创建数据表 tb_dept2,指定部门的名称唯一,输入的 S…

mysql 修改唯一约束_mysql如何修改唯一性约束跟主键约束

一、如何添加主键约束和唯一性约束 1、添加主键约束 执行语法: alter table tableName add primarykey(column_name);#千万别忘了加(),同时要保证表结构中没有其他的主键,因为一个表中只能有一个主键。 2、添加唯一性约束 执行语法: alter table tableName addunique(colum…

在mysql中怎么样添加唯一约束_mysql怎么添加唯一约束?

方法:1、创建表时,使用“CREATE TABLE 表名(字段名 数据类型 UNIQUE);”语句来添加;2、修改表时,使用“ALTER TABLE 表名 ADD CONSTRAINT 唯一约束名 UNIQUE(列名);”语句来添加。 (推荐教程:mysql视频教程) MySQL 唯一约束(Unique Key)是指所有记录中字段的值不能重复出现…

添加唯一约束

– 1.添加唯一约束 – 方式1&#xff1a;创建表时指定 use mydb1; create table user1( id int, phone_number varchar(20)unique – 指定唯一约束 ); insert into user1 values(1001,‘123’); – insert into user1 values(1001,‘123’); --不是唯一会报错 – 在MySQL中&…

SQL Server 2012 唯一约束(定义唯一约束、删除唯一约束)

文章目录 准备知识定义唯一约束使用SSMS工具定义唯一约束使用SQL方式定义唯一约束方式一&#xff1a;在创建数据表的时候定义唯一约束方式二&#xff1a;修改数据表定义唯一约束 删除唯一约束使用SSMS工具删除唯一约束方式一&#xff1a;在对象资源管理器中删除唯一约束方式二&…

数据库----------唯一约束、默认约束、零填充约束

目录 1.唯一约束&#xff08;Unique&#xff09; 1.概念 2.语法 3.添加唯一约束 4.删除唯一约束 2.默认约束(default) 1.概念 2.语法 3.添加默认约束 4.删除默认约束 3.零填充约束&#xff08;zerofill&#xff09;了解即可 1.概念 2.操作 3.删除 1.唯一约束&…

window连接远程桌面快捷键

1、使用window R 打开运行界面&#xff0c;输入mstsc按回车 2、或者按window键打开开始界面&#xff0c;在搜索框输入mstsc按回车 3、效果

远程桌面快捷键的使用

AltPage Up 从左到右切换程序。   AltPage Down从右到左切换程序。   AltInsert按照程序的打开顺序&#xff0c;依次切换程序。   AltHome 显示“开始”菜单。   CtrlAltEnd 跳转到“window 安全”界面&#xff0c; 类似于本地机器的CtrlAltDelete   Alt Delete 相当…

Windows常用快捷键,打开记事本,打开我的电脑,屏幕投影扩展,远程桌面快捷键

网上很多windows快捷键的说明&#xff0c;这里不多记录&#xff0c;本文主要记录开发者使用windows比较常用的快捷键&#xff0c;尤其是多个显示器或者打开多个应用。 切到桌面 ------点击最右下叫可以一键切到桌面或者wind 打开记事本 记事本打开没有快捷键&#xff0c;这…

计算机开启远程桌面服务,远程桌面服务 教您开启远程桌面服务

远程桌面服务是两台电脑通过互联网建立连接的一种系统必要服务&#xff0c;可以用电脑A控制电脑B的桌面&#xff0c;还可以利用电脑B还控制电脑A的桌面&#xff0c;如果远程桌面服务没有开启就会无法连接到远程计算机&#xff0c;下面玉米系统小编教大家远程桌面服务开启方法。…