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

打开客户端阅读

支持点赞、投币、收藏

立即体验

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

7 Days yo Die 七日杀服务器开服联机教程

1、购买后登录服务器(百度搜索莱卡云)game.lcayun.com 进入控制面板后会出现正在安装的界面,安装时长约5分钟左右 安装成功后你就可以看到我们的控制台界面 复制服务器ip地址打开游戏➡加入游戏 有两种方法加入游戏 第一种方法:…

电商平台商品数据的价值在哪里?如何实现批量抓取?

一、电商平台商品数据的价值探秘 在数字经济的浪潮中,电商平台商品数据如同一座蕴藏着无尽宝藏的矿山,其价值远超过我们表面的认知。今天,就让我们一起揭开这座矿山的神秘面纱,探寻其中的奥秘。 首先,电商平台商品数…

Java反射(含静态代理模式、动态代理模式、类加载器以及JavaBean相关内容)

目录 1、什么是反射 2、Class类 3、通过Class类取得类信息/调用属性或方法 4、静态代理和动态代理 5.类加载器原理分析 6、JavaBean 1、什么是反射 Java反射机制的核心是在程序运行时动态加载类并获取类的详细信息,从而操作类或对象的属性和方法。本质是JVM得…

c++:刷题必备 容器map的使用

文章目录 map的概念map的使用构造![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/30e9a697b50d47a591af6e9ae2bbb7d7.png)insert迭代器遍历 findoperator[]举例 map的概念 map是一个关联容器,里面的每一个位置pair,会存储两个值,一个是key,另一个是value. 我们可以…

【MySQL数据库开发设计规范】之表设计规范

欢迎点开这篇文章,自我介绍一下哈,本人姑苏老陈 ,是一名JAVA开发老兵。 本文收录于 《MySQL数据库开发设计规范》专栏中,该专栏主要分享一些关于MySQL数据库开发设计相关的技术规范文章,定期更新,欢迎关注&…

使用 Docker 部署 VS Code in The Browser

1)介绍 GitHub:https://github.com/coder/code-server 在日常学习工作中,Vscode 已成为我们首选的代码编辑器。然而,其局限性在于当我们从家到公司移动时,难以保持连续的编码体验。针对这一痛点,虽然市面上…

只需三步将Kimi接入微信公众号

今天我将手把手交大家如何把Kimi大模型接入微信公众号,创建属于你自己的公众号智能助理,让你的公众号具备智能对话、文件阅读、信息搜索等强大功能,同时提高用户互动率、减少人工客服压力等。 废话不多说,先来看看实际效果吧~ 一…

16 华三数据中心最流行的技术 M-LAG

STP和MTP(第二十二课)-CSDN博客 VRRP技术和浮动路由(第二十六课)_vrrp 浮动路由-CSDN博客 VRRP DHCP ACL NAT 网络核心路由技术综述 (第十课)-CSDN博客 04 交换机的IRF的配置-CSDN博客 1 M-LAG AI介绍 M-LAG(Multi-Chassis Link Aggrega…

Electron学习笔记(一)

文章目录 相关笔记笔记说明 一、轻松入门 1、搭建开发环境2、创建窗口界面3、调试主进程 二、主进程和渲染进程1、进程互访2、渲染进程访问主进程类型3、渲染进程访问主进程自定义内容4、渲染进程向主进程发送消息5、主进程向渲染进程发送消息6、多个窗口的渲染进程接收主进程发…

【python】python淘宝交易数据分析可视化(源码+数据集)

👉博__主👈:米码收割机 👉技__能👈:C/Python语言 👉公众号👈:测试开发自动化【获取源码商业合作】 👉荣__誉👈:阿里云博客专家博主、5…

模型推导:BG/NBD(预测用户生命周期(CLV)模型)

CLV(Customer Lifetime Value)指的是客户生命周期价值,用以衡量客户在一段时间内对企业有多大的价值。企业对每个用户的流失与否、在未来时间是否会再次购买,还会再购买多少次才会流失等问题感兴趣,本文中的BG/NBD模型…

PostgreSQL数据库创建只读用户的权限安全隐患

PostgreSQL数据库模拟备库创建只读用户存在的权限安全隐患 default_transaction_read_only权限授权版本变更说明 看腻了就来听听视频演示吧:https://www.bilibili.com/video/BV1ZJ4m1578H/ default_transaction_read_only 创建只读用户,参照备库只读模…

第三步->手撕spring源码之基于Cglib实现实例化策略

为什么深入研究spring源码? 其实每一个程序员每天的工作都是一贯的CRUD 实现业务和需求完成的操作。几年这样的操作让我感觉在这方面要提神能力 光靠CRUD是绝对不可能的事情 CRUD只是满足你作为一个搬砖人而已。编程能力提升?其实更多的编程能力的提升是…

用 Supabase CLI 进行本地开发环境搭建

文章目录 (零)前言(一)Supabase CLI(1.1)安装 Scoop(1.2)用 Scoop 安装 Supabase CLI (二)本地项目环境(2.1)初始化项目(2…

Promise.all和 race

Promise.all() all方法可以完成并行任务, 它接收一个数组,数组的每一项都是一个promise对象。返回值: 成功时:当数组中所有的promise的状态都达到resolved的时候,就返回包含所有 Promise 结果的数组,并且…

【C++】————类与对象(上)-基础知识

目录 1.面向过程和面向对象初步认识 2.类的引入 3.类的定义 类的两种定义方式: 成员变量命名规则的建议: 4.类的访问限定符及封装 4.1 访问限定符 ​编辑 【面试题】问题:C中struct和class的区别是什么? 4.2 封装 【面试…

数据分析中大数据和云计算

大数据和云计算 前言一、大数据二、大数据定义三、数据存储单位四、大数据存储技术五、大数据应用技术六、大数据特征七、数据容量八、数据类型的多样性结构化数据半结构化数据非结构化数据 九、获取数据的速度十、可变性十一、真实性十二、复杂性十三、价值十四、云计算十五、…

小白有什么副业可以做?

对于小白来说,以下是一些适合做副业的选择 1. 网络销售 可以在电商平台上开设小店,销售自己感兴趣的产品,如手工制品、二手物品、个人设计的商品等。 2. 做任务 目前网上最流行的就是做任务,因为简单无门槛,我推荐百…

partially initialized module ‘replicate‘ has no attribute ‘run‘

partially initialized module replicate has no attribute run(most likely due to a circular import) 在包名上停留查看impot 包的地址。 报错原因: 文件重名了,导入了 当前文件 。 修改文件名 即可。

分布式版本控制工具 - Git

文章目录 1. 概念介绍2. 客户端2.1 介绍2.2 仓库操作2.3 文件操作2.4 分支原理与操作2.5 标签2.6 远程仓库2.7 README与IGNORE 3. IDEA集成4. 版本号4.1 介绍4.2 文件操作4.2 分支操作 5. 命令5.1 介绍5.2 仓库操作5.3 文件操作5.4 分支操作5.5 标签操作5.6 远程仓库 1. 概念介…