找回密码
 立即注册
查看: 478|回复: 0

GPU随想——概论

[复制链接]
发表于 2021-12-11 15:16 | 显示全部楼层 |阅读模式
版权归作者所有,任何形式转载请联系作者。
作者:wc(来自豆瓣)
来源:GPU随想——概论

(胡写闲聊,难免有错,欢迎赐教,随时有停更危险……)
当今主要机器部件:CPU、GPU、存储器。总线(如PCIe)作桥梁。
CPU作主控,GPU受控,从某种角度来看似乎可看作一种高级“协处理器”。
GPU常用于多媒体(media)、图形(graphics)、通用计算(GPGPU)的加速。
特定的数字系统还可能装有其他类型的处理器,如DSP(digital signal processor,数字信号处理器。数字信号处理专用芯片,根据处理内容的特性(卷积),增加了多个MAC(加乘运算单元 ),采用哈佛结构提升处理速度)等。
计算机的组成分为两部分:协议与实现。
图形API上喜闻乐见的两大阵营:OpenGL与Direct3D。Vulkan为AMD Mantle的后裔,可视为OpenGL的后续版本,与DirectX 12对标,削减驱动层(的功能),将其部分动作交给程序员自行处理,偏低层,重性能。不过玩儿不好的话……
OpenGL的常见开源实现为mesa3d(类似的有,PCIe specs与各厂家的具体实现;语言中的接口interface,其上调用行为不变、其下实现按需变更),此项目由Brian Paul在93年带头开发。
由于OpenGL(ES)、Vulkan本质只是协议,实现多种多样,需要约束其具体执行行为。因此有了测试套件(VK-GL-CTS,Khronos Vulkan, OpenGL, and OpenGL ES Conformance Tests),从而保证行为一致、彼此兼容。
OpenGL ES 1/2/3为OpenGL的子集,便于在资源有限的平台(如移动平台)上实现。
软光栅器即光栅化过程均执行在CPU上,所谓“硬件加速”即光栅化过程跑在GPU上。
现实世界可看作是连续(模拟)的,而现今处理信息的硬件大多是离散的(数字(系统)),矛盾因此诞生!

-----------------------------我是面无表情的分割线-------------------------

3D硬件加速(简化步骤):应用->调用OpenGL(mesa实现OpenGL,将应用调用的API转换为GPU原生(本地)指令)->DRM([linux/drivers/gpu/drm,DRM,Direct Rendering Manager,直接渲染管理器] Linux内核环境下的GPU驱动,将指令转交给GPU、实现存储器间的调度等)->GPU执行指令,向显示器反馈结果。


化简的流程。嗯,中间貌似缺了些什么?那就对了,说明你对这块儿理解较深,嘻嘻嘻……
从上图来看,我认为把mesa视作图形驱动栈的一部分也未尝不可,只不过它是用户空间中的一个转换层。根据OpenGL的协议规定用户的操作(API的调用),再将其转换为GPU可执行的本地指令。图形驱动与其他硬件驱动还是有一定的差异,大多数外设驱动如USB、PCI总线等等(CPU管控制,驱动就是操作系统,如果是简单的嵌入式,可以将简单的控制程序烧至ROM;其他硬件都是通过总线与其相连,为了令CPU可以控制他们,就要根据其特异性编写“嵌入”操作系统的特殊程序:驱动程序,也就是描述如何令CPU与之交互),这些协议的关键都在传输上面,而图形处理上则赋予用户一定的灵活性,令用户可以针对GPU进行编程(跑着色器shader等等),所以就要更复杂(归根结底还是GPU核心的可编程流水线造成的),因而除了传输指令这个流程以外,还要用mesa层来将用户应用关乎图形的动作翻译为GPU指令。

mesa3d主要分为两大体系,传统(class)的mesa与后来新添的gallium。后者主要在架构上做了解耦,使新驱动加入进来更灵活。因此,新驱动一般都加入gallium。传统的mesa驱动主要针对OpenGL,各部结合的过于紧密,牵一发而动全身。(有意思的是,gallium早期的发起者是Tungsten Graphics,后被VMware收购,于是后来在VMware虚拟机里就能开启OpenGL的主机硬件加速了(也就是我现在用的家伙什),而且还有了自己的虚拟GPU。被收购一年后,Tungsten Graphics的联合创始人Jens Owen 从VMware出来,又和他人联手创建了LunarG!)
考虑到开源程度,主要讨论Intel与AMD系(So, NVIDIA FUCK YOU!!!!!!!!!!!!!!!!!!!!!!(山))。

Intel:Intel Open Source Technology Center  [Intel Open Source Technology Center]      
释出了GPU specs(Programmer's Reference Manuals (PRM))。这里仅讨论skylake架构。

AMD:Developer Guides, Manuals & ISA Documents
相对于Intel,AMD就显得没那么有诚意了,文档显得没有那么完整。而且,AMD的文档是递进式的,R5xx_Acceleration_v1.5最详细,后面基本以diff前一代体系的方式来写,看起来有点麻烦。最新相对完整(指《3D/Compute Register Reference Guide(寄存器指北)》、《Instruction Set Architecture(简记作ISA,指令集体系)》和《Acceleration(programming guide,编程手册)》三档齐全)的体系文档是 Sea Islands(海岛,为区别其前代Southern Islands(SI,南方群岛)常简记作CIK。但两者共享同一《Radeon Southern Islands Acceleration》编程手册)架构,因此就围绕此分析。

这两系GPU基本可以代表核显与独显进行讨论。根据Intel的动作,有可能再出独显,拭目以待……

-----------------------------我是面无表情的分割线-------------------------

其内容现在包罗万千,src文件夹简介(可参考Mesa source code tree overview与《Mesa Documentation》。热心提示:开源文档时效性是个严重问题,具体情况请结合具体代码,下同):

src/amd:亮点是vulkan文件夹下的RADV(Radeon Vulkan Driver)驱动,由开源贡献者针对AMD硬件所写的vulkan驱动,根据phoronix的评测,该驱动性能不俗(phoronix针对linux环境下的硬件进行评测,在显卡驱动评测这块做的很有特色,也能从中找到许多关于linux开发(包括mesa在内)的信息)。主要开发者为airlied、BNieuwenhuizen等人。

src/broadcom:博通开发的VideoCore是一款多媒体处理器,其中有3D加速引擎(V3D)。第4代产品VideoCore IV(简记作VC4)基于tiled渲染(tiled-base rendering,基于图块渲染)。结合src/gallium/drivers/v3d/,src/gallium/drivers/vc4/,再配合《VideoCore IV 3D Architecture Reference Guide》文档,相信会让你对tiled-base渲染的理解更进一层。现由离开Intel到博通的 Eric Anholt 主要实现。

src/compiler:转译几种着色器IR(Intermediate representation,中间语言)的编译器。

src/glx:glx库的实现,借此创建OpenGL上下文,并令OpenGL与X窗口系统相绑定。

src/EGL:mesa实现的EGL接口。简单来讲,EGL负责OpenGL与操作系统中窗口系统的交互,如创建OpenGL的context(上下文)、创建交换链等等。其功能与Linux平台下的GLX、Windows下的WGL相似。只不过它抽象出一层与具体系统无关的接口,供用户跨平台统一调用。

src/freedreno:针对高通 GPU Adreno,通过逆向工程手段制作的开源驱动。
(src/freedreno,src/broadcom应与Gallium3D中的对应驱动配合使用,前两者孤立出来是可供其他部分公共使用)

src/gallium:架构较新的驱动Gallium3D的源代码。
        src/gallium/auxiliary:七零八碎的工具,如远程调试,中间语言转换,某些驱动的辅助函数,甚至  
与系统有关的开辟内存(alloc memory)、管理线程等等。
        src/gallium/docs:文档喽~
        src/gallium/drivers:提供多种平台的驱动层。仅举几个关键的来说:freedreno(逆向工程的高通  
Adreno开源驱动,目前已写到a2xx至a6xx);i915(针对Intel i915系与i945系芯片组的所写的驱动,由于维护不善,i965系芯片组的驱动“暂时”被取消(2011就被取消了……mesa里的i965系通常代指i965系及其后续款式。而linux内核中的drm却只有915,并直接指代所有Intel芯片组)。因此要看i965驱动还是mesa class);llvmpipe(一种软光栅,借助LLVM编译器在运行期间生成CPU执行的代码。可根据平台利用SSE指令集加速);nouveau(逆向的nvidia驱动);panfrost(逆向的ARM mali驱动,包括Midgard与Bifrost系。类似的工程还有mesa lima);r300(AMD/ATI r300/r400/r500系GPU驱动);r600(AMD/ATI r600/r700/Evergreen/Northern Islands系GPU驱动);radeonsi(AMD Southern Island系GPU驱动);softpipe(一款软光栅器,速度慢却精度高);swr(即OpenSWR,Intel贡献的开源软光栅器,可根据具体机型运用AVX、AVX2与AVX512指令集加速,速度快,常用于科学方面的可视化计算);v3d/vc4:博通VideoCore开源驱动。      
         src/gallium/state_trackers:gallium的OpenGL状态追踪器(state tracker)现位于src/mesa/state_tracker(据文档称,后面可能会移走);clover(OpenCL的一个实现);nine(很有意思!);osmesa(离屏渲染状态追踪器);va(即va-api,video acceleration,视频加速状态追踪器);vdpau(即Video Decode and Presentation API for Unix,视频解码和显示状态追踪器);

src/intel:亮点是针对Intel GPU的开源Vulkan驱动,ANV。该项目由Intel的Jason Ekstrand主导。

src/mapi:OpenGL/ES1/ES2函数的映射工具。

src/mesa:传统mesa的文件夹。
        src/mesa/drivers:mesa的驱动。主要分为三类:X11、osmesa、dri。osmesa为离屏渲染驱动。dri:i915(Intel i915/i945(/i830)系芯片组GPU驱动);i965(Intel i965系芯片组GPU驱动);nouveau(逆向出的NVIDIA开源驱动);r200(ATI R200系GPU驱动);radeon(TI R100系GPU驱动);swrast(mesa的传统软光栅器的驱动)。
        src/mesa/main:mesa OpenGL状态管理。OpenGL不是状态机嘛,这层根据参数与当前环境(状态)等,将用户调用的API转换为适当上下文,传递给下层的驱动(src/mesa/drivers)。
        src/mesa/math:图形学中常会用到的一些数学变换或数据类型(矩阵、向量)的转换。
        src/mesa/program:与顶点着色器、片段着色器有关的GLSL编译器代码。
        src/mesa/state_tracker:gallium的OpenGL状态追踪器(怎么跑这儿来了……)。
        src/mesa/swrast:传统mesa的软光栅。可用于绘制点、线、三角形、位图、图片等等。详见文件夹中的NOTES文件。
        src/mesa/swrast_setup:用于粘合软光栅(src/mesa/swrast)与软T&L(src/mesa/tnl)的模块。详见其中的NOTES文件。
        src/mesa//tnl:tnl即transformation 'n lighting(变换与光照)。此模块功能为实现“软”变换与光照(即在CPU上计算)。详见文件夹中的NOTES文件。
        src/mesa/tnl_dd:利用硬件驱动处理tnl的代码。(dd->device driver)
        src/mesa/vbo:用于处理vbo(vertex buffer object,顶点缓冲区对象)的有关代码。
        src/mesa/x86-64:针对64位x86系统进行优化的代码及汇编代码。
        src/mesa/x86:针对32位x86系统进行优化的代码及汇编代码。

-----------------------------我是面无表情的分割线-------------------------

其实分析某个事物的的内部原理就是从其工作流程入手。
mesa也逃不出这个套路。
来回忆一下编写OpenGL程序的过程吧~
代码还没写,先冒出来个问题:怎么才能在程序中调用OpenGL库呢?
前面提到OpenGL只是一个跨平台协议,它的实现多种多样,运行的平台也是五花八门。而每个平台都有各自的图形窗口系统来管理用户与机器的交互。这样,就变成了首先要解决这两个问题。
接下来就轮到OpenGL的辅助工具登场了,按上述需求大约分为两个大类,
辅助创建窗口,并关联OpenGL与窗口的库,如:GLFW(推荐用此库,支持Vulkan,已更新至3.3),FreeGLUT、GLUT(太旧)等。
加载OpenGL库的库(有点儿绕),如:GLEW(仅针对OpenGL API),glad(支持OpenGL全家桶),GL3W等。
稍微完整的目录可以参见:
http://khronos.org维基上的《OpenGL Loading Library》、《Portal:Development Tools》或
http://opengl.org上的《GLUT and OpenGL Utility Libraries》。
可参见文章《GPU随想——OpenGL辅助工具》

-----------------------------我是面无表情的分割线-------------------------

参考文献
The Mesa 3D Graphics Library,mesa官网
The Mesa 3D Graphics Library latest documentation,gallium文档
openswr.org,Intel OpenSWR官网
x.org,X11的一种常用实现
Wayland,Wayland协议,有望成为X11的竞争、代替者
wikipedia.org,不解释,当概述文件很棒……
zale_lzj《mesa源码阅读笔记》,未完成,Windows平台
shoemaker《Linux环境下的图形系统和AMD R600显卡编程》,主要围绕EXA驱动
Litherum《Design of Mesa》,凌乱
igalia.com,有些不错的东东
Stéphane Marchesin《Linux Graphics Drivers: an Introduction》Linux图形驱动概述

2019/5/9:  王柏生《深度探索Linux操作系统》一半篇幅都在讨论linux下的图形子系统,如果作者把后半部分扩写成一本书,我也就不用写这堆东西了……
Mark J. Kilgard《OpenGL Programming for the X Window System》分析OpenGL与X的关系很透彻!缺点是略有过时。
Graham Sellers / Richard S Wright Jr. / Nicholas Haemel《OpenGL Superbible: Comprehensive Tutorial and Reference》宝典不解释……
John Kessenich/Graham Sellers/Dave Shreiner《OpenGL Programming Guide: The Official Guide to Learning OpenGL》板儿砖……
LearnOpenGL-CN,网上流行的一个OpenGL教程。
khronos.org
opengl.org
opengpu.org
转:

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

×
懒得打字嘛,点击右侧快捷回复 【右侧内容,后台自定义】
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Unity开发者联盟 ( 粤ICP备20003399号 )

GMT+8, 2025-5-15 00:44 , Processed in 0.143309 second(s), 26 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2025 Discuz! Team.

快速回复 返回顶部 返回列表