通用图形处理器设计GPGPU基础与架构(二)
一、前言
本系列旨在介绍通用图形处理器设计GPGPU的基础与架构,因此在介绍GPGPU具体架构之前,需要了解GPGPU的编程模型,了解软件层面是怎么做到并行的,硬件层面又要怎么配合软件,乃至定出合适的架构来实现软硬件协同。
二、通用编程背景
为了满足人们对GPU进行通用编程的需求,NVIDIA 公司于2007年发布了CUDA(Compute Unified Device Architecture,计算统一设备体系结构),支持编程人员利用更为通用的方式对GPU进行编程,更好地发挥底层硬件强大的计算能力,从而高效地解决各领域中的计算问题和任务。随后,苹果、AMD和 IBM 等公司也推出了OpenCL(Open Computing Language,开放运算语言)标准。该标准成为第一个面向异构系统通用并行编程的免费标准,适用于多核CPU 、GPGPU等多种异构并行系统。
三、GPGPU计算模型
本主要以CUDA并行编程中的一些架构概念来展示GPGPU的计算和存储模型。作为首个GPGPU编程模型,CUDA 定义了以主从方式结合单指令多线程(Single Instruction Multiple Threads,SIMT)硬件的多线程计算方式。
以上图的矩阵乘法为例,矩阵C中每个元素都可以由一个输入矩阵A的行向量和另一个输入矩阵B的列向量进行点积运算得到。C中每个元素的计算过程都可以独立进行,不存在依赖关系,因此具有良好的数据并行性。
在GPGPU中,承担并行计算中每个计算任务的计算单元称为线程(Thread),每个线程在一次计算任务过程中会执行相同的指令。在上例矩阵乘法中,每个线程会从矩阵A和B读取对应的行或列构成向量a和b, 然后执行向量点积运算,最后将结果c存到结果矩阵C的对应位置。
虽然每个线程输入数据不同,输出的结果也不同,但是每个线程需要执行的指令完全相同。也就是说, 一条指令被多个线程同时执行,这就是GPGPU 中的单指令多线程(Single Instruction Multiple Threads,SIMT)计算模型。
为了针对复杂的大规模通用计算场景将不方便处理,CUDA 引入了线程网格(thread grid)、线程块(thread block)、线程(thread)。Thread Block由多个Thread组成,而Grid又由多个Thread Block组成。因此,它们的关系就是Grid > Block > Thread。
在CUDA编程模型中,通常将代码划分为主机端(host)代码和设备端(device)代码,分别运行在CPU和GPGPU上。CPU硬件执行主机端代码,GPGPU硬件将根据编程人员给定的线程网格组织方式将设备端代码分发到线程中。
主机端代码通常分为三个步骤。①数据复制:CPU将主存中的数据复制到GPGPU中。②GPGPU启动:CPU 唤醒GPGPU线程进行运算。③数据写回:GPGPU运算完毕将计算结果写回主机端存储器中。
设备端代码常常由多个函数组成,这些函数被称为内核函数(kernel)。内核函数会被分配到每个GPGPU的线程中执行,而线程层次则由编程人员根据算法和数据的维度显式指定,如下图所示。
基于上面的线程层次,编程人员需要知道线程在网格中的具体位置,才能读取合适的数据执行相应的计算。因此,CUDA引入了为每个线程指明其在线程网格中哪个线程块的 blockIdx(线程块索引号)和线程块中哪个位置的threadIdx(线程索引号)。blockIdx有三个属性,x、y、z描述了该线程块所处线程网格结构中的位置。threadIdx 也有三个属性,x、y、z 描述了每个线程所处线程块中的位置。在一个Grid中:根据blockIdx和threadIdx,我们就能唯一锁定到某个线程,进而编程让其做具体计算。例如下面这段代码,调用线程进行了矩阵加法。
// Kernel定义
__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];
}
矩阵加法计算时,数据之间没有依赖性,每个线程都是并行独立地操作数据。
到此,可能会有个疑问,既然通用计算追根到底是索引到单个thread再做计算,那么假设没有block,我纯靠threadidx也能唯一索引到某个线程,block存在的意义到底是什么?。这就要引入共享存储器和全局存储器的概念了
首先,共享存储器的访问比全局存储器更快,共享存储器作用于一个线程块(thread block)内部,可以为同一个线程块内部的线程提供更快的数据访问。因此,通过合理划分块(block)的大小,可以充分利用数据的局部性原理减少对设备端全局存储器的访问,从而提高运算性能。此外,线程之间由于应用的特点可能不能完全独立。比如归约(reduction)操作需要邻近的线程之间频繁地交互数据,以协作的方式产生最终的结果,多个线程之间还可能需要相互同步,block的存在提高了线程之间的协作能力。
四、自线程到硬件结构
为了实现对大量线程的分配,GPGPU 对硬件功能单元进行了层次化的组织,如图所示。
它主要由流多处理器(Streaming MultiProcessor,SM)阵列和存储系统组成,两者由片上网络连接到L2高速缓存和设备端存储器上。每个流多处理器内部有多个流处理器(Streaming Processor,SP)单元,构成一套完整的指令流水线,包含取指、译码、寄存器文件及数据加载/存储(load/store)单元等,并以SIMT 架构的方式进行组织。GPGPU的整体结构、SM 硬件 和SP 硬件对应了线程网格、线程块和线程的概念,实现了线程到硬件的对应分配规则。
五、存储模型
GPGPU利用大量的线程来提高运算的并行度,这些线程需要到全局存储器中索引相应的数据。为了减少对全局存储器的访问,GPGPU架构提供了多种存储器类型和多样的存储层次关系来提高kernel函数的执行效率,如下表所示。
Memory Description | CUDA Memory Name |
所有的线程(或所有work-items)均可访问 | global memory |
只读存储器 | constant memory |
线程块(或work-group)内部线程访问 | shared memory |
单个线程(或work-item)可以访问 | local memory |
CUDA 支持多种存储器类型,线程代码可以从不同的存储空间访问数据,提高内核函数的执行性能。每个线程都拥有自己独立的存储空间,包括寄存器文件(Register File)和局部存储器(Local Memory),这些存储空间只有本线程才能访问。每个线程块允许内部线程访问共享存储器(Shared Memory),在块内进行线程间通信。线程网格内部的所有线程都能访问全局存储器(Global Memory),也可以访问纹理存储器(Texture Memory)和常量存储器(Constant Memory)中的数据。
① 寄存器文件(Register File)是 SM 片上存储器中最为重要的一个部分,它提供了与计算内核相匹配的数据访问速度。大容量的寄存器文件能够让更多的线程同时保持在活跃状态。这样当流水线遇到一些长延时的操作时,GPGPU可以在多个线程束之间快速地切换来保持流水线始终处于工作状态。这种特性在GPGPU中被称为零开销线程束切换(zero-cost warp switching),可以有效地掩藏长延时操作,避免流水线的停顿。
② 局部存储器(Local Memory)是每个线程自己独立的存储空间,局部存储器是私有的,只有本线程才能进行读写。
③ 共享存储器(Shared Memory)也是SM 片内的高速存储资源,它由一个线程块内部的所有线程共享。相比于全局存储器,共享存储器能够以类似于寄存器的访问速度读写其中的内容。
④ 全局存储器(Global Memory)位于设备端。GPGPU内核函数的所有线程都可对其进行访问,但其访存时间开销较大。
⑤ 常量存储器(Constant Memory)位于设备端存储器中,其中的数据还可以缓存在SM内部的常量缓存(Constant Cache)中,所以从常量存储器读取相同的数据可以节约带宽,对相同地址的连续读操作将不会产生额外的存储器通信开销。
⑥ 纹理存储器(Texture Memory)位于设备端存储器上,其读出的数据可以由纹理缓存(Texture Cache)进行缓存,也属于只读存储器。
六、同步机制
在SIMT 计算模型中,每个线程的执行都是相互独立的。然而在实际的应用和算法中,除向量加这种可完全并行的计算之外,并行的线程之间或多或少都需要某种方式进行协同和通信,例如:
① 某个任务依赖于另一个任务产生的结果,例如生产者-消费者关系;
② 若干任务的中间结果需要汇集后再进行处理,例如归约操作。
这就需要引入某种形式的同步操作,以Thread Block中的线程同步为例:
在CUDA 编程模型中,__syncthreads()可用于同一线程块内线程的同步操作,它对应的PTX 指令为bar 指令。该指令会在其所在程序计数器(Programe Counter,PC)位置产生一个同步栅栏(barrier),并要求线程块内所有的线程都到达这一栅栏位置才能继续执行,这可以通过监控线程的PC来实现。在线程同步的要求下,即便有些线程运行比较快而先到达bar指令处也要暂停,直到整个线程块的所有线程都达到bar指令才能整体继续执行。
七、总结
本文介绍了GPGPU编程的背景、CUDA编程实现步骤、软件到硬件的过度以及存储模型等内容,为后续介绍GPGPU架构提供理论基础。
相关文章:

通用图形处理器设计GPGPU基础与架构(二)
一、前言 本系列旨在介绍通用图形处理器设计GPGPU的基础与架构,因此在介绍GPGPU具体架构之前,需要了解GPGPU的编程模型,了解软件层面是怎么做到并行的,硬件层面又要怎么配合软件,乃至定出合适的架构来实现软硬件协同。…...

在一个使用了 Sass 的 React Webpack 项目中安装和使用 Tailwind CSS
要在一个使用了 Sass 的 React Webpack 项目中安装和使用 Tailwind CSS,可以按照以下步骤操作: 1. 安装 Tailwind CSS 及其依赖 首先,确保你的项目根目录下有 package.json 文件,然后运行以下命令来安装 Tailwind CSS 及其所需的…...

HDMI简介
本篇主要介绍HDMI常见接口以及TMDS传输技术。 文章目录 一、HDMI简介二、TMDS传输技术1.编码(encoder)2.并转串(serializer)——OSERDESE2原语3.单端转差分——OBUFDS源语 三、常见的几种信号传输方式 一、HDMI简介 HDMI(High-Definition Multimedia I…...

原作者带队,LSTM卷土重来之Vision-LSTM出世
与 DeiT 等使用 ViT 和 Vision-Mamba (Vim) 方法的模型相比,ViL 的性能更胜一筹。 AI 领域的研究者应该还记得,在 Transformer 诞生后的三年,谷歌将这一自然语言处理届的重要研究扩展到了视觉领域,也就是 Vision Transformer。后来…...

Fiddler 抓包工具抓https
Fiddler 抓包工具抓https...

详细谈谈负载均衡的startupProbe探针、livenessProbe探针、readnessProbe探针如何使用以及使用差异化
文章目录 startupProbe探针startupProbe说明示例配置参数解释 使用场景说明实例——要求: 容器在8秒内完成启动,否则杀死对应容器工作流程说明timeoutSeconds: 和 periodSeconds: 参数顺序说明 livenessProbe探针livenessProbe说明示例配置参数解释 使用…...

守望数据边界:sklearn中的离群点检测技术
守望数据边界:sklearn中的离群点检测技术 在数据分析和机器学习项目中,离群点检测是一项关键任务。离群点,又称异常值或离群点,是指那些与其他数据显著不同的观测值。这些点可能由测量误差、数据录入错误或真实的变异性造成。正确…...

python工作中遇到的坑
1. 字典拷贝 有些场景下,需要对字典拷贝一个副本。这个副本用于保存原始数据,然后原来的字典去参与其他运算,或者作为参数传递给一些函数。 例如, >>> dict_a {"name": "John", "address&q…...

中职网络安全wire0077数据包分析
从靶机服务器的FTP上下载wire0077.pcap,分析该文件,找出黑客入侵使用的协议,提交协议名称 SMTP 分析该文件,找出黑客入侵获取的zip压缩包,提交压缩包文件名 DESKTOP-M1JC4XX_2020_09_24_22_43_12.zip 分析该文件&…...

引领未来:在【PyCharm】中利用【机器学习】与【支持向量机】实现高效【图像识别】
目录 一、数据准备 1. 获取数据集 2. 数据可视化 3. 数据清洗 二、特征提取 1. 数据标准化 2. 图像增强 三、模型训练 1. 划分训练集和测试集 2. 训练 SVM 模型 3. 参数调优 四、模型评估 1. 评估模型性能 2. 可视化结果 五、预测新图像 1. 加载和预处理新图像…...

240707-Sphinx配置Pydata-Sphinx-Theme
Step A. 最终效果 Step B. 为什么选择Pydata-Sphinx-Theme主题 Gallery of sites using this theme — PyData Theme 0.15.4 documentation Step 1. 创建并激活Conda环境 conda create -n rtd_pydata python3.10 conda activate rtd_pydataStep 2. 安装默认的工具包 pip in…...

华为如何做成数字化转型?
目录 企业数字化转型是什么? 华为如何定义数字化转型? 为什么做数字化转型? 怎么做数字化转型? 华为IPD的最佳实践之“金蝶云” 企业数字化转型是什么? 先看一下案例,华为经历了多次战略转型…...

Python | Leetcode Python题解之第229题多数元素II
题目: 题解: class Solution:def majorityElement(self, nums: List[int]) -> List[int]:cnt {}ans []for v in nums:if v in cnt:cnt[v] 1else:cnt[v] 1for item in cnt.keys():if cnt[item] > len(nums)//3:ans.append(item)return ans...

TCP/IP模型和OSI模型的区别(面试题)
OSI模型,是国际标准化组织ISO制定的用于计算机或通讯系统间互联的标准化体系,主要分为7个层级: 物理层数据链路层网络层传输层会话层表示层应用层 虽然OSI模型在理论上更全面,但是在实际网络通讯中,TCP/IP模型更加实…...

UML建模工具Draw.io简介
新书速览|《UML 2.5基础、建模与设计实践 Draw.io是一个非常出色的免费、开源、简洁、方便的绘图软件,利用这款软件可以绘制出生动有趣的图形,包括流程图、地图、网络架构图、UML用例图、流程图等。它支持各种快捷键,免费提供了1000多张画图…...

qt udp 协议 详解
1.qt udp 协议链接举例 在Qt框架中,使用UDP协议进行通信主要依赖于QUdpSocket类。以下是一个基于Qt的UDP通信示例,包括UDP套接字的创建、绑定端口、发送和接收数据报的步骤。 1. 创建UDP套接字 首先,需要创建一个QUdpSocket对象。这通常在…...

ubuntu 换源
sudo apt update 错误如下 Ign:1 http://security.ubuntu.com/ubuntu focal-security InRelease Ign:2 http://us.archive.ubuntu.com/ubuntu focal InRelease Err:3 http://security.ubuntu.com/ubuntu focal-security Release SECURITY: URL redirect target…...

基于ssm的图书管理系统的设计与实现
摘 要 在当今信息技术日新月异的时代背景下,图书管理领域正经历着深刻的变革,传统的管理模式已难以适应现代社会的快节奏和高要求,逐渐向数字化、智能化的方向演进。本论文聚焦于这一转变趋势,致力于设计并成功实现一个基于 SSM&…...

python压缩PDF方案(Ghostscript+pdfc)
第一步:安装Ghostscript Ghostscript是一套建基于Adobe、PostScript及可移植文档格式(PDF)的页面描述语言等而编译成的免费软件。它可以作为文件格式转换器,如PostScript和PDF转换器,也为编程提供API。[1]PDF压缩本质…...

kotlin 基础
文章目录 1、安装 Java 和 Kotlin 环境2、程序代码基本结构3、变量的声明与使用4、数据类型5、数字类型的运算1)布尔类型2)字符类型3)字符串类型 6、 选择结构1)(if - else)2) 选择结构(when&am…...

Spring中的适配器模式和策略模式
1. 适配器模式的应用 1.1适配器模式(Adapter Pattern)的原始定义是:将一个类的接口转换为客户期望的另一个接口,适配器可以让不兼容的两个类一起协同工作。 1.2 AOP中的适配器模式 在Spring的AOP中,使用Advice&#…...

书生浦语大模型实战营---Python task
任务一 请实现一个wordcount函数,统计英文字符串中每个单词出现的次数,通过构建defaultdict字典,可以避免插入值时需要判断值是否存在 from collections import defaultdictdef word_count(text):#构建缓存reval defaultdict(int)words t…...

Chrome 127内置AI大模型攻略
Chrome 127 集成Gemini:本地AI功能 Google将Gemini大模型整合进Chrome浏览器,带来全新免费的本地AI体验: 完全免费、无限制使用支持离线运行,摆脱网络依赖功能涵盖图像识别、自然语言处理、智能推荐等中国大陆需要借助魔法,懂都懂。 安装部署步骤: 1. Chrome V127 dev …...

Yolo的离线运行
Yolo 的离线运行 运行环境准备 比较简单的办法是通过官方的github获取到对应的yolo运行需要的python环境-requirement.txt.通过如下地址可以获取到对应的文件和相应的说明以及实例。 Yolov5 git地址 为了让程序能本地话运行,我们还需要获取相应的模型权重文件&…...

【矿井知识】煤矿动火作业
简介 煤矿动火作业是指在煤矿环境下进行的任何形式的使用火源的工作。这些工作可能包括焊接、切割、加热、打磨等操作,这些操作都可能产生火花、火焰或高温,因此被称为动火作业。 动火作业的主要类型 焊接:包括电弧焊、气焊等,…...

设计模式使用场景实现示例及优缺点(结构型模式——享元模式)
结构型模式 享元模式(Flyweight Pattern) 享元模式,作为软件设计模式中的一员,其核心目标在于通过共享来有效地支持大量细粒度对象的使用。在内存使用优化方面,享元模式提供了一种极为高效的路径,尤其在处…...

开放式耳机哪款比较好?五款开放式耳机测评推荐
开放式耳机真的越来越火了,真的好多人问我,开放式耳机应该怎么选啊,所以这次我亲自测评了几款开放式耳机,作为数码博主这一篇文章就教大家如何挑选开放式耳机,当然最后还有五款开放式耳机的推荐给到大家,话…...

【网络安全】实验三(基于Windows部署CA)
一、配置环境 打开两台虚拟机,并参照下图,搭建网络拓扑环境,要求两台虚拟的IP地址要按照图中的标识进行设置,并根据搭建完成情况,勾选对应选项。注:此处的学号本人学号的最后两位数字,1学号100…...

hive中reverse函数
目录 前言基本函数介绍实战 前言 reverse函数,是一个常用的字符串处理函数,很多编程语言都有。最近开发中,遇到一个reverse解决的需求,发现自己尚未总结过,遂补上。 基本函数介绍 SELECT reverse(string_column) FR…...

SimpleTrack环境配置教程
SimpleTrack环境配置教程 conda create --name SimpleTrack python3.6 conda activate SimpleTrack git clone https://github.com/tusen-ai/SimpleTrack.git cd ./SimpleTrack/ # pip install opencv-python4.5.4.58 # 安装opencv-python报错,可尝试安此版本 pip …...