通用图形处理器设计GPGPU基础与架构(三)

一、前言

        前两篇已经介绍了 GPGPU 的背景 和 GPGPU 的编程模型相关的内容,本文将在 SIMT 计算模型的基础上,介绍 GPGPU 控制核心架构微体系结构的设计。

二、CPU-GPGPU 异构计算系统

       一个由 CPU 和 GPGPU 构成的异构计算平台如下图所示,GPGPU 通过 PCI-E(Peripheral Component Interconnect Express)接口连接到 CPU 上 。CPU 作为控制主体统筹整个系统的运行。 

        一次 kernel 函数的实现步骤如下:

       ① CPU 通过 PCI-E 与 GPGPU  进行通信,将程序中的 kernel 函数加载到 GPGPU 中的 SP 和 SM 上执行;

       ② 在驱动 kernel 函数的进行计算前,需要先将代码、配置和运行数据从硬盘加载到主机端存储器中;

       ③ 接着,由一系列运行和驱动 API 将数据传送到 GPGPU 的设备端存储器中;

       ④ 然后,GPGPU 启动 kernel 函数,通过大算力完成计算。

       ⑤ 最后,CPU 将结果由设备端存储器传送回主机端存储器,等待下一次调用。

        以上是一种 CPU-GPGPU 的异构计算架构。还有一种架构是 CPU 和 GPGPU 两者公用主机端存储器,例如 AMD 的异构系统架构(Heterogeneous System Architecture,HSA),它采用硬件支持的统一寻址,使得 CPU 和 GPGPU 能够直接访问主机端存储器,借助 CPU 与 GPGPU 之间的内部总线作为传输通道,通过动态分配系统的物理存储器资源保证了两者的一致性,提高了两者之间数据通信的效率。

       另有一种高性能变种是使用多个 GPGPU 并行工作。这种形式需要借助特定的互连结构和协议将多个 GPGPU 有效地组织起来。例如 NVIDIA 的 DGX  系统。它通过 NVIDIA 开发的一种总线及通信协议 NVLink,采用点对点结构、串列传输等技术,实现多 GPGPU 之间的高速互连。

三、GPGPU 架构

       不同型号的 GPGPU 产品虽有所差异,但其核心的整体架构存在一定的共性。下图为一个典型的 GPGPU 架构,其核心部分包含了众多可编程多处理器,NVIDIA  称之为流多处理器(Streaming   Multiprocesosr,SM),AMD 称之为计算单元(Compute Unit,CU)。每个 SM 又包含了多个流处理器(Streaming Processor,SP),NVIDIA称之为 CUDA 核心,AMD 称之为PE(Processin  Element),支持整型、浮点和矩阵运算等多种不同类型的计算。

        SM 构成了 GPGPU 核心架构的主体。它们从主机接口的命令队列接收 CPU 发送来的任务,并通过一个全局调度器分派到各个可编程多处理器上执行。SM 通过片上的互连结构与多个存储分区相连实现更高并行度的高带宽访存操作。每个存储分区包含了第二级缓存(L2 cache)和对应的 DRAM 分区。此外,SM 中包含了大量的 SP,如上图右侧所示,SP 由指令驱动,以流水化的方式执行指令,提高指令级并行度。

       面对数以万计的线程,硬件资源仍然有限,因此硬件会对海量的线程进行分批次的处理。 GPGPU 中往往采用线程束( NVIDIA 称为 warp,AMD 称为 wavefront) 的方式创建、管理、调度和执行一个批次的多个线程。当前,一种典型的配置是一个 warp 包含32个线程, 一个  wavefront 包括64个线程。当这些线程具有相同的指令路径时,GPGPU 就可以获得最高的效率和性能。

四、GPGPU 指令流水线

       流水线技术是利用指令级并行,提高处理器 IPC(Instruction Per Cycle)的重要技术之一。不同功能的电路单元组成一条指令处理流水线,利用各个单元同时处理不同指令的不同阶段,可使得多条指令同时在处理器内核中运行,从而提高各单元的利用率指令的平均执行速度。在大多数 GPGPU 架构中,虽然指令的执行粒度变为包含多个线程的线程束,但为了提高指令级并行,仍然会采用流水线的方式提高线程束指令的并行度,与单指令流水线相比,可以想象成水管变得更粗。

       上图显示了一种典型的 GPGPU 架构流水线设计。可以看到,每个线程束按照流水方式执行指令的读取(fetch)解码(decode)发射(issue)执行(execute)写回(writeback)过程。这一过程与标量流水线非常类似,但不同之处在于 GPGPU 的流水线以线程束为粒度执行,各个线程束相互独立。

       接下来将对上图涉及的所有模块进行详解。

4.1 前段:取指与译码

1.取指单元

       取指单元是根据程序计数器(Program Counter,PC)的值,从指令缓存中取出要执行指令的硬件单元。取出来的指令经过译码后会保存在指令缓冲中,等待指令后续的调度、发射和执行。

       在标量流水线中, 一般只需要一个 PC 来记录下一条指令的地址。但由于 GPGPU 中同时存在多个线程束且每个线程束执行的进度可能并不一致,取指单元中就需要保留多个 PC 值,用于记录每个线程束各自的执行进度和需要读取的下一条指令位置。这个数目应该与可编程多处理器中允许的最大线程束数量相同。

2.指令缓存

       指令缓存接收到取指单元的PC, 读取缓存中的指令并发送给译码单元进行解码。指令高速缓存(I-Cache)可以减少直接从设备端存储器中读取指令的次数。本质上指令缓存也是缓存,可以采用传统的组相联结构FIFOLRU(Least Recently Used) 等替换策略来进行设计。取指单元对指令缓存的访问也可能会发生不同的情况:如果命中(cache hit),指令会被传送至译码单元;如果缺失(cache miss),会向下一层存储请求缺失的块,等到缺失块回填指令缓存后(refill),访问缺失的线程束指令会再次访问指令缓存。

3.译码单元

       译码单元对指令缓存中取出的指令进行解码,并且将解码后的指令放入指令缓冲中对应的空余位置上。根据 SASS 指令集的定义和二进制编码规则,译码单元会判断指令的功能、指令所需的源寄存器、目的寄存器和相应类型的执行单元或存储单元等信息,进而给出控制信号,控制 整个线程束流水线的运行。

4. 指令缓冲

       指令缓冲用于暂存解码后的指令,等待发射。考虑到每个 SM 中会有许多线程束在执行,指令缓冲可以采用静态划分的方式来为每个线程束提供专门的指令条目,保留已解码待发射的指令。每个指令条目(entry)一般包含一条解码后的指令和两个标记位,即一个有效位(valid)和一个就绪位(ready)。有效位表示该条指令是有效的已解码未发射指令,而就绪位表示该指令已经就绪可以发射。就绪的指令往往需要通过诸如记分牌(scoreboard)的相关性检查等一系列条件,并且需要有空闲的硬件资源才能得以发射。 

       指令缓冲中的有效位还会反馈给取指单元,表明指令缓冲中是否有空余的指定条目用于取指新的线程束指令。如果有空余条目,应尽快利用取指单元从指令缓存中获得该线程束的后续指令;如果没有空余条目,则需要等待指令缓冲中该线程束的指令被发射出去后条目被清空才能进行指令读取。

4.2 中段:调度与发射

       指令的调度与发射作为指令流水的中段,连接了前段取指和后段执行部分,对流水线的执行效率有着重要的影响。

1. 调度单元

       调度单元通过线程束调度器(warp scheduler)选择指令缓冲中某个线程束的就绪指令发射执行。发射会从寄存器文件中读取源寄存器(source register)传送给执行单元。调度器则很大程度上决定了流水线的执行效率。为了确保指令可以执行,调度单元需要通过各种检查以确保指令就绪并且有空闲执行单元才能发射。这些检查包括没有线程在等待同步栅栏没有数据相关导致的竞争和冒险等

2.记分牌

       记分牌单元(scoreboard)主要是检查指令之间可能存在的相关性依赖,如写后写(Write-After-Write,WAW)写后读(Read-After-Write,RAW),以确保流水化的指令仍然可以正确执行。记分牌算法通过标记目标寄存器的写回状态为“未写回”,确保后续读取该寄存器的指令或再次写入该寄存器的指令不会被发射出来。直到前序指令对该目的寄存器的写回操作完成,该目的寄存器才会被允许读取或写入新的数据。

3.分支单元和 SIMT 堆栈

       对于指令中存在条件分支的情况,例如if…else…语句,它们会破坏 SIMT 的执行方式。 条件分支会根据线程束内每个线程运行时得到的判断结果,对各个线程的执行进行单独控制,这就需要借助分支单元,主要是活跃掩码(active mask) SIMT 堆栈进行管理,解决一个线程束内线程执行不同指令的问题。

4.寄存器文件和操作数收集

       指令执行之前会访问寄存器文件(register file)取源操作数。指令执行完成后还需要写回寄存器文件完成目的寄存器的更新。寄存器文件作为每个可编程多处理器中离执行单元最近的存储层次,需要为该可编程多处理器上所有线程束的线程提供寄存器数值。

       出于电路性能、面积和功耗的考虑,寄存器文件会分 Bank 设计,且每个 Bank 只有少量访问端口(如单端口)的设计方式。对不同 bank 的数据同时读取可以在同周期完成,但是不同请求如果在同一 Bank,就会出现Bank Conflict 而影响流水线性能。

4.3 后段:执行与写回

       作为指令执行的后段,计算单元是对指令执行具体操作的实现,存储访问单元则完成数据加载及存储操作。

1.计算单元

       GPGPU 需要为每个可编程多处理器配备许多相同的流处理器单元来完成一个线程束中多个线程的计算需求,同时还配备了多种不同类型的计算单元,用来支持不同的指令类型,如整型、浮点、特殊函数、矩阵运算等。不同类型的指令从寄存器文件中获得源操作数, 并将各自的结果写回到寄存器文件中。

       作为基本的算术需求,GPGPU 中提供了较为完整的算术逻辑类指令,支持通用处理程序的执行。在 NVIDIA  GPGPU 架构中,流处理器单元体现为 CUDA 核心,它提供了整型运算能力和单精度浮点运算能力。不同的架构会配备不同数量的双精度浮点硬件单元, 以不同的方式对双精度浮点操作进行支持,以满足高性能科学计算的需求。

2.存储访问单元

       存储访问单元负责通用处理程序中 load  store 等指令的处理。由于配备了具有字节寻址能力的 load  store 等指令,GPGPU 可以执行通用处理程序。

       GPGPU 一般会包含多种类型的片上存储空间,如共享存储器、L1 数据缓存、常量缓存和纹理缓存等。存储访问单元实现了对这些存储空间的统一管理, 进而实现对全局存储器的访问。同时针对 GPGPU 的大规模 SIMT 架构特点,存储访问单元还配备了地址生成单元(Address Generation Unit,AGU)、冲突处理(bank conflict)、地址合并、MSHR(Miss Status Handling Registers)等单元来提高存储器访问的带宽并减小开销。当需要访问共享存储器中的数据时,冲突处理单元会处理可能存在的 Bank conflict,并允许在多周期完成数据的读取。对于全局存储器和局部存储器中的数据,load/store 指令会将同一线程束中多个线程产生的请求合并成一个或多个存储块的请求。面对 GPGPU 巨大的线程数量,存储访问单元通过合并单元将零散的请求合并成大块的请求,利用 MSHR 元支持众多未完成的请求,有效地掩盖了对外部存储器的访问延时,提升了访问的效率。

五、总结

       本文介绍了 GPGPU 的经典架构和指令流水线,下一篇将针对影响 GPGPU 性能最大的分支情况介绍解决方案。

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

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

相关文章

树结构添加分组,向上向下添加同级,添加子级

树结构添加分组&#xff0c;向上向下添加同级&#xff0c;添加子级 效果代码实现页面js 效果 代码实现 页面 <el-tree :data"treeData" :props"defaultProps" :expand-on-click-node"false":filter-node-method"filterNode" :ref&…

Hive的基本操作(查询)

1、基础查询 基本语法 select 字段列表|表达式|子查询 from 表(子查询|视图|临时表|普通表) where [not] 条件A and|or 条件B --先&#xff1a;面向原始行进行筛选 group by 字段A[,字段B,...] > 分组【去重处理】 having 聚合条件(非原始字段条件) --再&#x…

iPhone数据恢复:如何从iPhone恢复误删除的短信

来自iPhone的意外删除的短信可能很关键。它们可能是来自您常用应用程序、银行交易、付款收据的重要通知&#xff0c;也可能是来自朋友的重要文本、孩子的学校通知等。 如果您也从iPhone丢失了此类消息&#xff0c;我们在这里分享如何在没有备份以及有备份的情况下在iPhone上恢…

热门软件缺陷管理工具2024:专业评测与建议

国内外主流的10款软件缺陷管理工具软件对比&#xff1a;PingCode、Worktile、禅道、Tapd、Teambition、Tower、JIRA、Bugzilla、MantisBT、Trac。 在软件开发过程中&#xff0c;管理缺陷和漏洞常常成为一项挑战&#xff0c;尤其是在项目规模庞大时。选择一个高效的软件缺陷管理…

object-C 解答算法:两数之和(leetCode-1)

两数之和(leetCode-1) 题目如下图:(也可以到leetCode上看完整题目,题号1) 解答方法一: 最简单的方法就是双指针遍历数组.代码如下 - (NSMutableArray *)sumOfTwoNumbers:(NSMutableArray *)array target:(int)target {NSMutableArray * resultArray [[NSMutableArray alloc…

探索Facebook在人工智能领域的最新进展

在当今快速发展的科技领域中&#xff0c;人工智能&#xff08;AI&#xff09;作为一项关键技术&#xff0c;正在逐步改变着社交媒体的面貌。作为全球最大的社交平台之一&#xff0c;Facebook积极探索和应用人工智能&#xff0c;以提升用户体验、增强平台安全性并推动技术创新。…

数学建模·灰色关联度

灰色关联分析 基本原理 灰色关联分析可以确定一个系统中哪些因素是主要因素&#xff0c;哪些是次要因素&#xff1b; 灰色关联分析也可以用于综合评价&#xff0c;但是由于数据预处理的方式不同&#xff0c;导致结果 有较大出入 &#xff0c;故一般不采用 具体步骤 数据预处理…

实战案例:用百度千帆大模型API开发智能五子棋

前随着人工智能技术的迅猛发展&#xff0c;各种智能应用层出不穷。五子棋作为一款经典的棋类游戏&#xff0c;拥有广泛的爱好者。将人工智能技术与五子棋结合&#xff0c;不仅能提升游戏的趣味性和挑战性&#xff0c;还能展现AI在复杂决策问题上的强大能力。在本篇文章中&#…

WPF实现一个带旋转动画的菜单栏

WPF实现一个带旋转动画的菜单栏 一、创建WPF项目及文件1、创建项目2、创建文件夹及文件3、添加引用 二、代码实现2.ControlAttachProperty类 一、创建WPF项目及文件 1、创建项目 打开VS2022,创建一个WPF项目&#xff0c;如下所示 2、创建文件夹及文件 创建资源文件夹&…

LVS+Nginx高可用集群---keepalived原理与实战

1.高可用集群架构keepalived双机主备原理 高可用&#xff1a;(HA) 部署nginx存在两台nginx。当主节点的nginx宕机停止服务的时候&#xff0c;nginx备用机起到跟nginx(主) keepalived的概念&#xff1a;解决单点故障&#xff1b;组件免费&#xff1b;可以实现高可用HA机制&…

Unity不用脚本实现点击按钮让另外一个物体隐藏

1.首先在场景中创建一个按钮和一个其他随便什么东西 2.点击按钮中的这个加号 3.然后将刚刚你创建的物体拖到这里来 4.然后依次点击下面这些给按钮绑定事件 5.运行游戏并点击按钮&#xff0c;就会发现拖进来的物体消失了 总结&#xff1a;如果按钮的功能单一&#xff0c;可以使用…

EPLAN 去掉PDF中的红色跳转标识

EPLAN PDF图纸导出后体验跳转标识会有红色标识&#xff0c;如何去掉呢&#xff1f;下面介绍一下方法&#xff1a; 此为现象&#xff1a; EPLAN 2.9的帮助文档里提示&#xff1a; 在导出的 PDF 文档中&#xff0c;跳转后的跳转目标现在通过红色的闪烁框进行标识。可能的跳转目…

尚硅谷大数据技术-数据湖Hudi视频教程-笔记03【Hudi集成Spark】

大数据新风口&#xff1a;Hudi数据湖&#xff08;尚硅谷&Apache Hudi联合出品&#xff09; B站直达&#xff1a;https://www.bilibili.com/video/BV1ue4y1i7na 尚硅谷数据湖Hudi视频教程百度网盘&#xff1a;https://pan.baidu.com/s/1NkPku5Pp-l0gfgoo63hR-Q?pwdyyds阿里…

让AI语言模型自由飞翔:LangChain框架的奇妙世界

今天&#xff0c;我将为大家揭开一项令人激动的技术——LangChain。想象一下&#xff0c;如果能将人工智能的强大能力与我们日常使用的数据和工具无缝连接&#xff0c;那将开启怎样崭新且无限的可能&#xff01; LangChain&#xff0c;一个专为大型语言模型设计的框架&#xf…

数据分析——numpy教程

1.NumPy&#xff1a; 是Python的一个开源的数值计算库。可以用来存储和处理大型矩阵&#xff0c;比python自身的嵌套列表结构要高效&#xff0c;支持大量的维度数组与矩阵运算&#xff0c;此外也针对数组运算提供大量的数学函数库&#xff0c;包括数学、逻辑、形状操作、排序、…

Python实现批量转换图片格式:告别单调乏味的图片圈套!

各位小伙伴们&#xff0c;你是不是也厌倦了那些单调乏味的图片格式&#xff1f;又或者饱受不同格式的图片文件所困扰&#xff1f;别急&#xff0c;今天小编来给你送上一份活泼有趣的Python教程&#xff0c;让我们一起告别单调&#xff0c;迎接多彩多姿的图片世界吧&#xff01;…

R包:TreeAndLeaf二分类树构建R包

介绍 树形图显示了二叉树&#xff0c;重点是表示树元素之间的层次关系。树状图包含节点、分支(边)、根和叶。根是分支和节点的来源&#xff0c;指示到叶的方向&#xff0c;即终端节点。 树形图布局的大部分空间用于排列分支和内部节点&#xff0c;留给叶子的空间有限。对于大…

异常检测算法

目录 一、异常检测算法功能&#xff1a;二、正态&#xff08;高斯&#xff09;分布&#xff1a;三、异常检测算法执行过程&#xff1a;四、如何选择特征&#xff1a;五、评估异常检测算法&#xff1a; 一、异常检测算法功能&#xff1a; 异常检测算法用来检测数据集中的一些异…

OpenGL笔记二之glad加载opengl函数以及opengl-API(函数)初体验

OpenGL笔记二之glad加载opengl函数以及opengl-API(函数)初体验 bilibili赵新政老师的教程看后笔记 code review! 文章目录 OpenGL笔记二之glad加载opengl函数以及opengl-API(函数)初体验1.运行2.重点3.目录结构4.main.cpp5.CMakeList.txt 1.运行 2.重点 3.目录结构 01_GLFW_…

oracle控制文件详解以及新增控制文件

文章目录 oracle控制文件1、 控制文件包含的主要信息如下&#xff1a;2、查看目前系统的控制文件信息&#xff0c;主要是查看相关的字典视图 oracle新增控制文件 oracle控制文件 控制文件是一个很小的二进制文件(10MB左右)&#xff0c;含有数据库结构信息&#xff0c;包括数据…