近距离看GPU计算(3)

article/2025/9/1 20:19:11

在先前文章《近距离看GPU计算(2)》中,我们谈到现代GPU发展出SIMT(Single Instruction Multiple Thread)的执行结构,硬件线程池的线程们有相对独立的运行上下文,以Warp为单位分发到一组处理单元按SIMD的模式运行。这些Warp内的线程共享同样的PC,以锁步的方式执行指令,但是每个线程又可以有自己的执行分支。很自然衍生的一个问题就是现代GPU如何有效的处理Branch Divergence(分支分歧)?一方面为适应复杂图形渲染以及通用计算的要求,GPU编程语言像其它高级语言一样需要支持各种各样的流控制(Flow Control)指令,比如if\switch\do\for\while等等,这些指令都会导致分支分歧。另一方面GPU并行计算的特点要求所有处理单元整齐划一地执行相同指令,才能够取得性能最大化。如何较好地解决这两种不同要求导致的冲突,一直是GPU研究中的热点难点问题。在这里笔者没有能力深入探讨,只是浅尝辄止做一般介绍,主要求这个系列内容完整,不足甚至谬误之处,请各位看官不吝指正。

一,分支分歧对性能的影响

这一节我们首先来讨论下分支分歧对GPU性能的影响。以如下if\else代码为例,我们看下GPU一般是如何来处理分支分歧的?

if (cond) {...} else {...}

假设一个Warp中有16个线程判断条件为真,另外16个线程条件为假,所以一半线程会执行if中的语句,另一半线程执行else中的语句。这看起来像个悖论,我们知道Warp中的线程同一时刻只能执行相同的指令。实际上遇到分支分歧时GPU会顺序执行每个分支路径,而禁用不在此路径上的线程,直到所有有线程使能的分支路径都走完,线程再重新汇合到同一执行路径。如下图所示,每个分支都有些线程不干活或者干无用功,Warp实际上需要执行的指令数目大增。假设每个分支任务量大致相同,分支分歧造成的性能损失少则原先的一半,最坏的情况如果每个线程执行分支都不一致,性能下降为最高时候的1/32。

所以无论在设计算法还是分配处理数据的时候,我们都要小心尽量避免同一个Warp内线程出现分支分歧的状况,在遇到流控制指令的时候,最好能够选择同样的路径。

二,如何实现Reconvergence

上一节我们讲了Warp的线程产生了分支分歧之后,为求性能最佳,不可能让它们一直放任自流,最终还是要尽可能在合适时机把它们重新汇合(Reconverge)起来。但这一切是如何实现的呢?按照参考1的说法,“The SM uses a branch synchronization stack to manage independent threads that diverge and converge” 。下面根据可接触到的文献我们看看大概是如何实现的,不一定跟GPU产商的实际做法一致我们称这个Warp运行时栈为SIMT Stack,每个Warp拥有一个SIMT栈用于处理SIMT执行模式中的分支分歧。首先我们需要先确定分支分歧的最近重汇合点(Reconvergence Point),一般可以选用造成分支分歧节点的直接后序支配节点(Immediate post-dominator,若控制流图的节点n 到终结节点的每一条路径均要经过节点d,则称节点d后序支配节点n,如d与n之间没有任何其他节点后序支配n,则称节点d直接后序支配节点n),这可以通过编译时的控制流分析得到。如下图所示,左边是我们假想的一段GPU伪代码,右边是对应的控制流图,我们假设SIMD通道的数目是4,每个节点边上的掩码数字代表通道上线程在该节点基本块有没有使能。

SIMT栈结构每个条目由执行指令PC、分支重汇合PC(RPC)和使能线程掩码三部分组成。下图反映了执行流从节点B分支分歧到节点E重新汇合时SIMT栈的更新过程。执行的时候,遇到流控制指令,我们将各个分支依次入栈,栈顶条目的PC会被送到取指单元开始相应分支路径的处理,只有条目掩码中使能的线程会处于活跃状态,当下一条PC等于栈顶条目RPC的时候,说明该分支已经到了汇合点,栈顶条目会被弹出,开始下一分支的处理以至所有执行线程汇合并共同执行接下来的指令。值得注意的是真实环境下GPU都设计有一些特殊指令来维护SIMT栈。

下图表示上面代码在时间轴上的执行过程,实心箭头表示对应线程在该执行节点处于活跃状态,反之空心箭头代表不活跃状态。

基于SIMT栈的Reconvergence方案并不完美,其中一个很大的问题是Warp内线程细粒度同步的时候很容易引发死锁。按照Nvidia的说法,"algorithms requiring fine-grained sharing of data guarded by locks or mutexes can easily lead to deadlock, depending on which warp the contending threads come from."。以下面代码为例,某幸运线程拿到锁之后,在最近重汇合点C等着与大部队接头,不幸的是它无法执行下面的Exch指令以释放锁,导致其它线程只能在B处空转,形成死锁。

从更高的层次上理解,分支分歧导致的顺序执行只发生在Warp内的线程,Warp之间却相互不受干扰,这种不一致的处理方式对算法移植的适应性还是可预测性都会带来影响。Nvidia从Volta GPU开始做出了改进,提出了"Independent Thread Scheduling"的方法,使得所有线程无关所在Warp可以具有同样并发执行能力,为此相比之前的GPU其Warp内所有线程共享PC以及运行栈,Volta GPU的线程都分别有各自的PC和运行栈,如下图所示。

如此针对同样的GPU程序以及分支分歧,Volta与之前的GPU相比有截然不同的调度行为。我们注意到在Volta中所有的Warp线程并没有一起强制汇合执行Z基本块,主要考虑到Z可能作为生产者需要提供其它执行分支依赖的的数据。回到我们先前死锁的例子,在Volta中这个死锁便可迎刃而解。如果我们明显了解相关分支不存在同步行为,为优化性能计,CUDA提供了 __syncwarp() 函数以便强制汇合。

主要参考资料:

  1. NVIDIA Tesla: A Unified Graphics and Computing Architecture

  2. Dynamic Warp Formation and Scheduling for Efficient GPU Control Flow

  3. https://developer.nvidia.com/blog/inside-volta/

  4. General-Purpose Graphics Processor Architectures

~~~~~~~~~~~~~~~~~~~~~~~~~~~~

如果觉着内容有帮助,请帮忙关注、点赞、在看并分享给更多的朋友。谢谢!


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

相关文章

CPU线程与超线程技术

文章目录 一、CPU线程与OS线程1. CPU中的thread2. OS中的thread 二、HT/SMT技术1. 定义2. 原理3. 带来的问题 三、SIMT与SIMD1. SIMT2. SIMD3. 对比 一、CPU线程与OS线程 1. CPU中的thread CPU中的线程来自同步多线程(SMT,Simultaneous Multi-threadin…

GPU 软硬件基本概念

术语: single instruction, multiple thread (SIMT): a single instruction is executed on several function units in parallel GPU的硬件结构中与CUDA相关的几个概念:thread block grid warp sp sm streaming processor(sp): 最基本的处理单元&…

GPU异构计算基础知识

CUDA Toolkit Documentation (nvidia.com) host CPU和内存 (host memory)Device GPU和显存 (device memory) SIMT模型与SIMD模型的区别 SIMD(Single Instruction Multi Data,单指令多数据)模型要求同一个向量中的所有元素要在统一的同步组中一起执行,…

GPU硬件架构以及运行机制笔记

本文是对向往大神的文章的一个笔记。 想阅读原文章移步博客园搜索向往 原文章比较长,这是一个精简和自己的一些理解 这篇文章要带着下面的问题去看 1、GPU是如何与CPU协调工作的? 2、GPU也有缓存机制吗?有几层?它们的速度差异多…

4. CUDA编程手册中文版---硬件实现

第四章 硬件实现 更多精彩内容,请扫描下方二维码或者访问https://developer.nvidia.com/zh-cn/developer-program 来加入NVIDIA开发者计划 NVIDIA GPU 架构围绕可扩展的多线程流式多处理器 (SM: Streaming Multiprocessors) 阵列构建。当主机 CPU 上的 CUDA 程序调…

SMIT介绍

System Management Interface Tool(系统管理界面工具) 软件安装与维护(Sofeware Installation and Maintenance) 软件许可管理(Sofeware License Management) 版本管理(Manage Editions) 设备管理&#…

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

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

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

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

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

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

从GPU编程到SIMT核心

本文转自:从GPU编程到SIMT核心 - 知乎 (zhihu.com) 1、前言&本文重点 在 GPGPU 显得愈发重要的今天,仅凭 nVidia, AMD 提供的编程接口来了解 GPU 未免显得太单薄了些。时至今日, 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中&…