GPU prompt

提问:

  1. GPU是如何与CPU协调工作的?

  2. GPU也有缓存机制吗?有几层?速度差异是多少?

  3. GPU渲染流程有哪些阶段?他们的功能分别是什么?

  4. Early-Z技术是什么?发生在哪个阶段?这个阶段还会发生什么?

  5. SIMD和SIMT是什么?他们的好处是什么?co-issue呢?

  6. GPU是并行处理的吗?硬件层是如何设计并实现的呢?

  7. GPC、TPC、SM是什么?Warp又是什么?它们和Core、Thread之间的关系如何?

  8. 顶点着色器和像素着色器可以是同一处理单元吗?为什么?

  9. 像素着色器最小处理单位是一像素吗?为什么?会带来什么影响?

  10. Shader中if、for会降低渲染效率吗?为什么?

  11. 渲染相同面积的图形,三角形的数量会影响效率吗?为什么?

  12. GPU Content是什么?有什么作用?

  13. 造成渲染瓶颈的问题可能有哪些?该如何避免或优化它们?

 

GPU是什么

GPU(Graphics Processing Unit)是图形处理单元,是专门用于绘制图像和处理单元数据的特定芯片。GPU不是显卡,是显卡上最核心的部件。

GPU物理架构

由于纳米工艺的引进,GPU可以将数以亿计的晶体管和电子器件集成于芯片内。当GPU与散热风扇、PCI插槽、HDMI等部件组成后,就成为了显卡。

显卡不能独立工作,需要装载在主板上,结合CPU、内存、显存、显示器等硬件设备,组合成完整的PC。

 

GPU微观物理结构

NVidiaTesia架构:

  • 拥有7组TPC(Texture/Processor Cluster,纹理处理簇)

  • 每个TPC有两SM(Streaming Multiprocessor,流多处理器)

  • 每个SM包含8个SP(StreamingProcessor,流处理器)

  • 2个SFU(Special Function Unit,特殊函数单元)

  • L1缓存、MT Issue(多线程指令获取)、C-Cache(常量缓存)、共享内存

  • 除了TPC核心单元,还有与显存、CPU、系统内存交互的各种部件。

8dc894c4dc6ad912807fa0b9ca261b0f9122a637.png@656w_518h_!web-article-pic.avif

 

NVidiaFermi架构:

  • 有16个SM(Streaming Multiprocessor,流多处理器)

  • 两个WarpScheduler(线程束)

  • 两组共32个Core

  • 16组加载存储单元(LD/ST)

  • 4个特殊函数单元(SFU)

  • 分发单元(Dispatch Unit)

  • 每个Core有一个FPC(浮点数单元)、一个ALU(逻辑运算单元)

 

NVidiaMaxwell架构

  • 采用了Maxwell的GM204,拥有4个GPC

  • 每个GPC有4个SM,对比Tesia架构来说在处理单元上有了很大提升

 

NVidiaTuring架构

  • 6个GPC(图形处理簇)

  • 36个TPC(纹理处理簇)

  • 72个SM(流多处理器)

  • 每个GPC上有6个TPC、每个TPC上有两个SM

  • 4608个CUDA核

  • 72个RT

  • 576个Tensor核

  • 288个纹理单元

  • 12x32位GDDR6内存控制器(共384位)

  • 每个SM包含64个CUDA核(CUDA是NVIDIA推出的统一计算架构)

  • 每个SM包含8个Tensor核(Tensor Core是专为执行张量或矩阵运算而设计的专用执行单元)

  • 每个SM包含256kb的寄存器文件

 

GPU架构的共性

纵观所有GPU架构,存在着很多相同概念的部件

  • GPC(图形处理簇)

  • TPC(纹理处理簇)

  • Thread(线程)

  • SM、SMX、SMM(StreamMultiprocesser,流多处理器)

  • Warp线程束、WarpScheduler(Warp编排器)

  • SP(StreamProcessor,流处理器)

  • Core(执行数学运算的核心)

  • ALU(逻辑运算符单元)

  • FPU(浮点数单元)

  • SFU(特殊处理单元)

  • ROP(RenderOutputUnit,渲染输入单元)

  • Load/StoreUnit(加载存储单元)

  • L1Cache(L1缓存)

  • L2Cache(L2缓存)

  • SharedMemory(共享内存)

  • RegisterFile(寄存器)

GPU是天然并行的,现代GPU的架构是以高度并行能力设计的

 

GPU微观物理结构

  • 包含关系:GPC==>TPC==>SM==>CORD

  • SM包含PolyMorphEngine(多边形引擎)、L1Cache(L1缓存)、SharedMemory(共享内存)、Core(执行数学运算的核心)等。

  • CORE又包含ALU、FPU、ExecutionContent(执行上下文)、Detch、解码(Decode)

 

GPU渲染总览

Fermi架构运行机制总览图:

从Fremi开始NVIDIA使用类似的原理架构,使用一个GigaThreadEngine来管理所有正在运行的工作,GPU被划分为多个GPCs(GraphicProcessingCluster),每个GPC拥有多个SM(SMX、SMM)和一个光栅化引擎(RasterEngine),它们其中有很多的连接,最显著的是Crossbar,他可以连接GPCs和其他功能性模块(例如ROP和其他子系统)

程序员编写的Shader是在SM上完成的,每个SM包含许多为线程执行数学运算的Core(核心)。例如:一个线程可以是顶点或像素着色器调用。这些Core和其他单元由WarpScheduler驱动,WarpScheduler管理一组32个线程作为Warp(线程束)并将要执行的指令移交给DispatchUnits

 

 

GPU逻辑管线

以Fermi家族的SM为例子,进行说明:

1-3

1、程序通过图形API(DirectX、Glsl、WebGL)发出drawcall指令,指令被推送到驱动程序,驱动程序检查指令合法性,然后将指令放到GPU可读的PushBuffer中。

2、经过一段时间或显示调用flush指令后,驱动程序把PushBuffer的内容发送给GPU,GPU通过主机接口(HostInterface)接受命令,并通过前端(FrontEnd)处理这些命令。

3、在图元分配器(PrimitiveDistributor)中开始工作分配,处理IndexBuffer中的顶点产生三角形分成批次(batches),然后发送给多个GPCs。这一步理解就是提交上来n个三角形,分配给这几个GPC同时处理。

4、在GPC中,每个SM中的PolyMorphEngine负责通过三角形索引(triangleIndices)取出三角形的数据(vertexData),即图中的VertexFetch模块。

5、取出数据后,在SM中以32个线程为1组的线程束(Warp)来调度,来开始处理顶点数据

6、SM的Warp调度器会按照顺序分发指令给整个Warp,单个Warp中的线程会锁步(lock-step)执行各自的指令,如果线程碰到不激活执行的情况也会被遮掩(be masked out)

7、Warp指令可一次完成,也可被多次调度,例如通常SM中的LD/ST(加载存取)单元数量明显少于基础数学操作单元

8、由于某些指令比其他指令需要更长时间来完成,特别是内存加载,warp调度器可能会简单的切换到另一个没有内存等待的Warp,这是GPU如何克服内存读取延迟的关键,只是简单的切换活动线程组。

9、一旦被Warp完成了Vertex-Shader的所有指令,运算结果会被ViewportTransform模块处理,三角形会被裁剪,然后准备栅格化,GPU会使用L1和L2缓存来进行Vertex-Shader和Pixel-Shader的数据通信。

10、接下来这些三角形将会被分割,再分配给多个GPC,三角形的范围决定了他将被分配到哪个光栅化引擎(rasterEngines),每个RasterEngines覆盖了多个屏幕上的Tile,这等于把三角形的渲染分配到了多个Tile上面。也就是像素阶段就把按三角形划分变成了按显示像素划分了。

11、SM上的AttributeSetup保证了从Vertex-Shader来的数据经过插值后是Pixel-Shader可读的。

12、GPC上的光栅引擎(RasterEngines)在他接收到的三角形上工作,来负责这些三角形的像素信息生成,同时会处理背面剔除和Early-Z剔除。

13、32个像素线程将被分为1组,或者说8个2x2的像素块,这是在像素着色器上面的最小工作单元,在这个像素线程内,如果没有被三角形覆盖就会被遮掩,SM的waro调度器会管理像素着色器的任务

14、接下来的阶段就和Vertex_Shader中的逻辑步骤完全一致,但是变成了在像素着色器线程中执行。由于不耗费任何性能就能获取一个像素内的值,导致锁步执行非常便利,所有的线程可以保证所有的指令可以在同一点。

15、像素着色器已经完成了颜色的计算和深度值的计算,在这个点上,我们必须考虑三角形的原始API顺序,然后才将数据移交给ROP(RenderOutputUnit,渲染输入单元)一个ROP内部有很多ROP单元,在ROP单元中处理深度测试,和FrameBuffer的混合,深度和颜色的设置必须是原子操作,否则两个不同的三角形在同一个像素点就会有冲突和错误

 

 

Early-Z

早期GPU的渲染管线的深度测试是在像素着色器之后才执行,这样会造成很多本不可见的像素执行了耗性能的计算。后来,为了减少像素着色器的额外消耗,将深度测试提前到像素着色器之前,这就是Early-Z技术的由来。Early-Z技术可以将很多无效的像素提前剔除,避免它们进入耗时严重的像素着色器。

Early-Z剔除的最小单位不是1像素,而是像素块(2x2)

但是,以下情况会导致Early-Z失效:

1、开启AlphaTest:由于AlphaTest需要在像素着色器后面的AlphaTest阶段作比较(DirectX的discard,OpenGL的clip),所以无法在像素着色器之前决定该像素是否被剔除。

2、开启AlphaBlend:启用了Alpha混合的像素很多需要与FrameBuffer做混合,无法执行深度测试,也就无法利用Early-Z技术。

3、关闭深度测试:Early-Z是建立在深度测试开启的条件下,关闭深度测试,也就无法使用Early-Z技术

4、开启Multi-Samping:多采样会影响周边像素,而Early-Z阶段无法得知周边像素是否被裁剪,故无法提前剔除

5、其他任何导致需要混合后面颜色的操作。

 

 

SIMD和SIMT

SIMD(Single Instruction Multiple Data)是单指令多数据,在GPU的ALU单元内一条指令可以处理多维向量(一般是4D)的数据。比如,有以下shader指令:

float4 c = a + b;//ab都是float4类型

对于没有SIMD的处理单元,需要4条指令将4个float类型相加。

但有了SIMD技术,只需要一条指令便可完成。

SIMT(Single Instruction Multiple Threads,单指令多线程)是SIMD的升级版,可对GPU中单个SM中的多个Core同时处理同一指令,并且每个Core存取的数据可以是不同的。

SIMT_ADD c,a,b

上述指令会被同时送入在单个SM中被编组的所有Core中,同时执行运算,但a,b,c的值可以不一样。

 

 

co-issue

co-issue是为了解决SIMD运算单元无法充分利用的问题,由于float数量的不同,ALU的利用率从100依次下降到75、50、25。

为了解决着色器在低维向量利用率低的问题,可以通过合并1D与3D或2D与2D的指令。

但是,对于向量运算单元(VectorALU)如果其中一个变量既是操作数又是存储数的情况,无法启用co-issue技术

 

 

CPU与GPU对比

CPU是一个具有多种功能的优秀领导者。他的优点在于调度、管理、协调能力强,但是计算能力一般

GPU相当于一个接受CPU调度“拥有大量计算能力”的员工。

 

 

CPU-GPU异构系统

根据CPU与GPU是否共享内存,可分为两种类型的CPU-GPU架构

分离式架构:CPU和GPU各有独立缓存和内存,它们通过PCI-e等总线通讯。这种结构的缺点在于PCI-e相对于两者具有低带宽和高延迟,数据的传输成为了其中的性能瓶颈。使用广泛,如PC等。

耦合式架构:CPU和GPU共享内存和缓存。AMD的APU采用的就是这种结构,主要应用于游戏主机中,如PS4,智能手机等。

在存储管理方面,分离式结构中CPU和GPU各自拥有独立的内存,二者共享一套虚拟地址空间,必要时会进行内存拷贝。耦合式结构中,GPU没有独立内存,与CPU共享系统内存,由MMU进行存储管理。

 

 

GPU资源机制

内存架构:

GPU与CPU类似,也有多级缓存结构:寄存器、L1缓存、L2缓存、GPU显存、系统显存

他们的存取速度从寄存器到系统内存依次变慢。

由此可见,shader直接访问寄存器,L1L2缓存还是比较快的,但访问纹理、常量缓存和全局内存非常慢,会造成很高的延迟。

 

 

GPU内存分布在Ram存储芯片或者GPU芯片上,它们物理上所在的位置,决定了他们的速度、大小以及访问规则。

全局内存(Global memory)位于片外存储体中,容量大、访问延迟高、传输速度较慢、使用二级缓存(L2 cache)做缓冲

本地内存(Local memory)一般位于片内存储体中,变量、数组、结构体等都存放在此处,但是有大数组、大结构体以至于寄存器区放不下它们,编译器在编译阶段就会将它们放到片外的DDR芯片中(最好的情况也是放于L2 cache),且将它们标记为Local。

共享内存(Shared memory)位于每个流处理器组中(SM)中,访问速度仅次于寄存器

寄存器内存(Register memory)位于每个流处理器组中(SM)中,访问速度最快的存储体,用于存放线程执行时所需要的变量。

常量内存(Constant memory)位于每个流处理器组中(SM)中和片外的RAM存储器中。

纹理内存(Constant memory)位于每个流处理器组中(SM)中和片外的RAM存储器中。

 

 

GPU资源管理模型

 

 

 

CPU-GPU数据流

  1. 将主存的处理数据复制到显存中

  2. CPU指令驱动GPU

  3. GPU中每个运算单元并行处理,此步会从显存存取数据

  4. GPU将显存结果传回主存

 

 

Shader运行机制

在执行阶段,CPU将Shader二进制指令经由PCI-e推送到GPU端。GPU在执行代码时,会用Content将指令分成若干Channel推送到各个Core的存储空间。

 

 

对于SIMT架构的GPU,汇编指令有所不同,变成了SIMT特定指令代码

并且Context以Core为单位组成共享的结构,同一个Core的多个ALU共享一组Context

如果有多个Core,就会有更多的ALU同时参与Shader计算, 每个Core执行的数据是不一样的,可能是顶点、图元、像素等任何数据。

 

 

 

GPU Content和延迟

由于SIMT技术的引入,导致很多同一个SM内的很多Core并不是独立的,当它们当中有部分Core需要访问到纹理、常量缓存和全局内存时,就会导致非常大的卡顿(Stall)

如图:有四种上下文(Content)它们共用一组运算单元ALU

假设第一组Context需要访问缓存或内存,会导致2-3周期的延迟,此时调度器会激活第二组Content以利用ALU

当第二组卡住又会依次激活3-4组Content了,直到第一组Content恢复运行或所有都被激活。

延迟的后果是每组Content总体执行时间被拉长了

越多Content可用就越可以提升运算单元吞吐量。

 

 

总结:

顶点着色器和像素着色器都是在同一单元中执行的(在原来的架构中vs和ps的确是分开的,后来nv把这个统一了)vs是按照三角形来处理的,ps是按照像素来并行处理的

vs和ps中数据是通过L1和L2缓存传递的

warp和thread都是逻辑上的概念,sm和sp都是物理上的概念,线程数 != 流处理器数

 

 

  1. 尽量使用自己拓展的几何实例化替代Unity提供的静态合批、动态合批、前者将合并mesh增加vbo的内存占用,后者则会增加cpu端的耗时开销

  2. 尽量减少顶点数与三角面数,前者减少顶点着色器的运算,减少GPU显存中FrameData的内存存储,后者减少片元着色器的消耗

  3. 避免每帧提交Buffer数据,比如Unity的CPU版本的粒子系统,可以使用GPU版本的粒子系统,将修改数据移动到GPU,避免大片的透明粒子特效,会造成严重的Overdraw

  4. 减少渲染状态的设置与获取,如在Update获取设置Shader的属性或者公共变量。CPU是通过MMIO获取寄存器数据,这将耗费更多的时间周期

  5. 3D物体尽量使用LOD处理顶点与面数的消耗,开启Mipmap减少贴图缓存命中的丢失

  6. 避免AlphaTest的使用,会造成Early-Z失效

  7. 避免三角面过小,会加剧过度绘制的情况,也就是前面提到的三角形只占3个像素点,却使用了12个线程去计算像素值然后屏蔽其余9个计算结果

  8. 在寄存器数量与变体中寻找平衡,使用if变量达成静态分支,取代变体。一方面可以减少变体数量,另一方面也可以使URP中的SRP Batch更高效合批

  9. 尽量避免动态判断分支也就是Shader中的if true和false都会走的情况

  10. 减少复杂函数的调用,从硬件架构上就可以看出特殊函数处理单元是远远小于正常计算的单元的

 

 

 

Gefore RTX 2060验证

 

本文禁止转载或摘编

  • 2
  • 5
  • 分享

热门评论(0)

noface.gif

请先登录后发表评论 (・ω・)

表情发布

看看下面~来发评论吧

h5-download-logo@3x.png

打开客户端阅读

支持点赞、投币、收藏

立即体验

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

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

相关文章

Cocos 2048从创建到发布上线

二、审核通过之后上线流程 代码通过审核之后,会通过站内信和微信消息发送通知,在管理后台,点击提交发布,去备案

File类~路径、创建文件对象

路径分为相对路径(不带盘符),绝对路径(带盘符) 路径是可以存在的,也可以是不存在的 创建文件对象的三个方法:

IDEA-SpringBoot项目启动类位置错误导致启动报错

文章目录 前言:本文为SpringBoot项目启动类位置错误导致启动报错解决方案 笔者在初学SpringBoot项目时遇到过因启动类位置错误导致项目启动报错现象,总结如下: SpringBoot启动发送请求后遇到如下错误: Postman界面信息&#xff1…

速了解及使用布隆过滤器

布隆过滤器 介绍 概念:是一种高效查询的数据结构 作用:判断某个元素是否在一个集合中。(但是会出现误判的情况) 实现原理 加入元素: 当一个元素需要加入到布隆过滤器中时,会使用一组哈希函数对该元素进…

JVM调优:JVM运行时数据区详解

一、前言 Java运行时数据区域划分,Java虚拟机在执行Java程序时,将其所管理的内存划分为不同的数据区域,每个区域都有特定的用途和创建销毁的时间。 其中,有些区域在虚拟机进程启动时就存在,而有些区域则是随着用户线程…

CANape测量分析标定

CANape创建工程及标定 1 创建工程 1. 创建ape工程 打开CANape软件,创建新的ape工程 2.添加数据库文件 通过添加Device(确定信号源)的方式加载数据库文件 A2L:通过添加CCP、 XCP、VX1000的Device DBC:对总线报文检测 CAN CDD: 诊断功能 Diagnostic 如需导入MAP文件…

道格拉斯普克算法(DP)的点云轮廓线简化

1、背景介绍 由于点云无法精确刻画目标对象边缘信息,因此常规提取的边缘点直接相连所生成的轮廓线,锯齿现象显著,与真实情况相差甚远(图b所示)。 道格拉斯-普克(Douglas-Peuker)抽稀算法是用来对…

【数据库系统工程师】2024年5月考前最后冲刺指南

一、备考关键: 高效率的备考方式:多轮迭代学习 △ 基础阶段 △ 大面积撒网(60%) 略读-> 做题 -> 回顾 -> 精读 △ 积累阶段 △ 有针对性的突破(30%) 完成所有章节之后,进行真题测试&#x…

爬取深圳2024年链家二手房数据,共3000条数据(其他城市也可)

文章目录 专栏导读1.目标2.导入相关库3.获取每个二手房的链接4.获取每个链接中的相关数据5.保存数据6.数据展示 专栏导读 ✍ 作者简介:i阿极,CSDN 数据分析领域优质创作者,专注于分享python数据分析领域知识。 ✍ 本文录入于《python网络爬虫…

鲜活很有感染力的女生图片_活力满满有生命力女生图片

鲜活很有感染力的女生图片_活力满满有生命力女生图片

公有云Linux模拟UDP端口并抓包

目录 写在前面操作步骤服务端开启UDP端口并监听客户端连接Wireshark抓包查看 写在前面 关于具体的操作,请参考我的上一篇文章 公有云Linux模拟TCP三次挥手与四次握手(Wireshark抓包验证版) 在本文,仅介绍与上一篇不同的地方。 操…

R语言:GSEA分析

#安装软件包 > if (!requireNamespace("BiocManager", quietly TRUE)) install.packages("BiocManager") > BiocManager::install("limma") > BiocManager::install("org.Hs.eg.db") > BiocManager::install("…

【算法刨析】完全背包

完全背包与01背包的区别 01背包对于一个物品只能选择一次,但是完全背包可以选择任意次; 思路 和01背包类似,01背包我们只需要判断选或不选,完全背包也是如此,不同的是,对于这个物品我们在判断选后在增加一…

【送书福利第七期】你好!Java(文末送书)

文章目录 编辑推荐内容简介作者简介目录前言/序言 编辑推荐 适读人群 :程序员;相关院校师生 本书以轻松幽默的语言,从零开始介绍Java语言。书名来源于编程语言中最经典的Hello World程序,寓意带读者从入门到精通。 书中每章都设有总结与扩展…

vue3延迟加载(异步组件​)defineAsyncComponent

最简单用法 Index.vue: <script setup> import { onMounted, defineAsyncComponent } from vue import ./index.cssconst Child defineAsyncComponent(() > import(./Child.vue))onMounted(() > {}) </script><template><div class"m-home-w…

Linux学习笔记4

书接上文&#xff0c;我们上两篇在讲建立最小Linux系统时要创建的几个脚本&#xff0c;接下来我们继续说一下 建立最小系统之创建文件系统所需文件&#xff08;续&#xff09; 之后我们返回etc目录&#xff0c;再返回system目录&#xff0c;接着使用“cd lib”命令进入到lib …

现在做电商迟吗?那是你不知道今年黑马,视频号小店重磅来袭

大家好&#xff0c;我是电商笨笨熊 24年想做电商&#xff0c;还能不能做&#xff1f; 当然可以。 电商是一个长期的市场&#xff0c;只要用户有需求&#xff0c;那么电商就会一直存在&#xff1b; 尤其是近几年来无货源模式爆火&#xff0c;对于我们商家来说这种无需自备货…

flutter 使用Scrollbar 时出现 滚动条不置顶问题

Flutter 使用 CupertinoScrollbar 、Scrollbar 与 ListView.builder 结合使用时&#xff0c; 当把 ListView.builder 边距设置为 padding: const EdgeInsets.all(0) 的时候&#xff0c; Scrollbar 的滚动条不置顶。 如图&#xff1a;右侧边上的滚动条 解决方法&#xff1a; …

抖店的爆品,到底是选出来的还是推出来的?我的看法是......

我是王路飞。 做电商的&#xff0c;你要说你对爆品没有想法&#xff0c;那劝你不要做了。 有人认为做抖店&#xff0c;爆品都是选出来的&#xff0c;毕竟方向不对&#xff0c;努力白费。 也有人认为做抖店&#xff0c;爆品都是推出来的&#xff0c;再好的产品&#xff0c;达…

KNIME 报告扩展

文档对应的 KNIME AP 版本为 5.2 介绍 本指南介绍了 KNIME 报告扩展&#xff0c;并展示了如何创建简单和高级报告。 本指南更新于 2024/05/13&#xff0c;最新版请访问指北君网站 https://havef.fun/knime-cn/knime-doc/ KNIME 报告扩展允许您根据工作流程的结果创建静态报告。…