GPU软件栈的变革:如何应对人工智能和机器学习的挑战?

薪科技快评 2024-02-15 09:13:06
【GPU】完整的软件栈

前言

GPU编程揭秘

本期,我们将深入探讨程序如何控制 GPU 做事情。我们将了解 GPU 架构和编程方法,以及如何利用 GPU 的功能模块来实现高效计算。掌握这些知识,您将能够充分发挥 GPU 的潜力,并为各种领域带来更强大的计算能力。GPU都有什么功能模块。以及如何用可控的方式把它们部署到硬件上,但是光有硬件不行啊,总得让软件能用得上。本期就来看看程序是如何控制GPU做事情的。

程序需要通过操作系统提供的的硬件端口读写,直接操作图形硬件。

如果每个程序都需要对每个操作系统的每个硬件写一遍。开发效率非常低,

应用程序编程接口(API):

沟通桥梁,高效协作。

抽象形成公共接口,程序轻松告诉底下做什么,底下负责高效执行。api。

跨操作系统、多设备兼容:程序只需编写一次,即可在不同操作系统和硬件平台上运行,无需针对不同设备进行适配。API写一遍就行,几乎不必考虑操作系统和硬件的区别。图形API由硬件厂商实现往下翻译成对应件的操作。

技术的发展与演进 从API实现到设备驱动接口DDI

API的实现分层,增加了一个抽象层称为设备驱动接口DDI,该层可以公用大量部分,使不同实现变得更加高效和便捷,实现技术的发展与演进。API的不同实现也存在大量可以公用的部分。于是API的实现又进行了分层,增加的一个抽象层称为设备驱动接口DDI。

DDI往上属于操作系统,负责数据有效性检查,内存分配等。

DDI往下是驱动,负责各个硬件特别的部分。

相当于操作系统把API翻译成DDI驱动,驱动把DDI翻译成对硬件的操作。

这就是图形API软件栈的架构。

图形API软件栈的架构1-Direct3Dd->D3D

- 优化后的文字:

我们将在本文中探讨多种有代表性的 API,如 DirectX 12 和 Vulkan 的架构,以理解它们在现实世界中的运作方式。api为例,看看他们现实中的架构。第一个是微软的Direct3Dd,D3D。这里只讨论Windows上的官方实现。

这个API不跨平台,但跨厂商。

- Windows XP 时代,软件栈与理想状态不符。

- 操作系统提供 D3D 运行时,往上是 API,往下是 DDI。

- 厂商提供内核态驱动,框架称为 XDM。Windows xp的时代,软件站就和理想状况不一样。操作系统提供一个D3D runtime,往上是API,往下是DDI 厂商提供一个内核态驱动,这个框架称为xdm。

随着稳定性、性能和共享资源需求的不断增长,Vista 时代见证了运行时和厂商驱动进一步细分为用户态和内核态两部分。这两部分各自拥有独立的 DDI,创造了更高级别的抽象和更安全的系统。vista时代,runtime和厂商驱动都进一步分成了用户态和内核态两部分。这两部分里分别有自己的DDI。

D3D API 调用流程优化:

程序调用 D3D API 时,D3D Runtime 验证数据,经由用户态 DDI 到达厂商用户态驱动 UMD。D3D api的时候,D3D runtime会进行一些数据验证。通过用户态的DDI到达厂商提供的用户态驱动UMD。

UMD将shader字节码编译成厂商专用指令,转换命令队列并传至内核态。dxg kernel是内核里的运行时部分,负责显存分配及设备中断管理等。把shader字节码编译成厂商专用的指令,转换命令队列等,传到内核态。内核里的runtime部分叫做dxg kernel。做显存分配、设备中断管理等。

经过内核态DDI调用厂商提供的内核态驱动KMD,

做一些地址翻译等厂商专用的操作,最后传给GPU执行。

这个架构称为WDDM。

把驱动分为用户态和内核态,并把大部分代码移到用户态,能大大提高稳定性。

优化后的文章:

D3D runtime和dxg kernel的引入,让厂商驱动开发变得更加便捷,工作量大幅减少。同时,不同厂商之间的差异也缩小,驱动质量整体提升。D3D runtime和dxg kernel这两个操作系统组件的存在,厂商开发驱动的过程从作文题直接变成了填空题。工作量大大减少,这还使得不同厂商之间的区别变小,总体质量有所提升。

Vista之后,得益于优化的驱动程序,蓝屏问题大幅减少。目前,D3D版本主要有9、11、12,其中11和12最为常用。vista之后因为驱动造成的蓝屏远少于xp的时代,多年以来D3D发展出了很多版本,目前最常用的是9 11 12。

2-OpenGL

API和用户DDI大不相同,代码没有多少兼容性。每出一版,程序和UMD都得大改甚至重写才能用上。

跨平台图形 API:OpenGL

* 开放标准,跨平台

* 广泛使用于游戏、图形应用

* 由 Khronos 集团维护API。opengl,它由Khronos发布。

Khronos只组织标准协商会议,

API要支持什么,还得看组织里的软硬件厂商。

在 Windows 平台上,OpenGL 面临微软自家图形 API——Direct3D 的激烈竞争。多年来,微软一直试图在 Windows 上压制 OpenGL,但由于用户的强烈反对而多次失败。Windows上,OpenGL和微软自己的D3D存在直接竞争关系,以至于微软一直想方设法要在Windows上掐OpenGL。很多次尝试都因为用户的强烈反对而作罢。

优化文案:

OpenGL 依赖于可安装用户驱动 (ICD) 框架,由 Windows 提供,以便与系统兼容。并没有为OpendGL做多少事情,只是提供了一个框架叫做可安装用户驱动,ICD。

OpenGL runtime的UMD可让硬件厂商轻松实现跨平台兼容性。无论在用户态还是内核态,都只需经过dxg kernel和同一个KMD,简化开发流程,提升效率。OpenGL runtime的UMD。到了内核态,也要经过dxg kernel和同一个KMD。

* Linux上的OpenGL实现方式分为两种:厂商实现和基于Mesa框架。

* Mesa框架提供开源OpenGL运行时,通过DDI调用厂商驱动操作GPU。

* Mesa框架的优点在于开源、跨平台兼容性更佳。Linux,OpenGL有两种实现方式,一种是完全由厂商实现整个OpenGL,另一种方式是基于Mesa的框架。Mesa提供了一个开源的OpenGL runtime,并通过DDI调用厂商驱动来操作GPU。

后来进一步扩展出了对OpenGL ES、Vulkan等API的支持。

OpenGL从90年代初的1.0到最后一版4.6,都是向下兼容的。

OpenGL本身都是一样的。是和窗口打交道的部分略有不同,程序的平台适配并不难。

OpenGL ES甚至把窗口系统给抽象出来,成为EGL。进一步简化了跨平台。

注意,虽然OpenGL 和 OpenGL ES非常相似,

api来看待。

NVIDIA CUDA:

- 跨平台计算 API,专为 NVIDIA GPU 设计。

- 仅限计算,可与其他图形 API 交互。

- 计算结果可供图形流水线使用。API 是NVIDIA的CUDA,它是跨平台的,但不跨厂商。正式来说只能在NVIDIA的GPU上跑。这是一个只有计算的API,需要的话可以和其他的图形API交互,还计算的结果交给图形流水线。

* CUDA是一种强大的并行计算平台,不仅适用于图形处理,还可用于有限元模拟、神经网络训练等纯计算任务。

* CUDA提供了一些独特的功能,例如共享内存,可以显著提高GPU的计算效率。

* 利用CUDA的并行计算能力,可以大幅缩短计算时间,提高计算效率。CUDA被用来做纯计算,比如有限元模拟,神经网络训练等。CUDA提供的一些功能并不存在于图形API里,并不是更高层的抽象。比如CUDA一开始就提出了shared memory这个概念。用好的话可显著提高GPU的效率。

CUDA开创了图形API的新时代,其设计影响了后来的compute shader。它弥补了当时图形API的不足,使其能够进行复杂的计算。API里是没有的,只能通过CUDA。后来的compute shader也是受到CUDA的影响而设计出来的。

横向比较一下现在的api,有这么一个规律。

CUDA CUDA 和 Metal 均为垂直整合的 API,从软件到出都由单一公司拥有,在增加新功能时反应迅速,无需协商,满足开发者的需求。和Metal这种从软件到硬件都是一个厂商拥有的API。在硬件有个新功能之后,可以直接通过API暴露出来。不需要跟别的厂商讨论,反应很快。

OpenGL、OpenGL ES 和 Vulkan 由 Khronos 拥有接口,硬件厂商拥有实现。各 API 采用向上扩展的方式进行设计。、OpenGL ES、Vulkan这三个API的模式。都是Khronos拥有接口,硬件厂商拥有实现。在设计中使用了自己向上的方式。

他们都提供了扩展机制,可以在不更新api版本的情况下扩充api。

随着时间的推移,API的发展趋势是变得更加精简。让程序处理更多任务,减少对runtime和驱动程序的依赖,从而提高效率和灵活性。API,可以看到他们发展趋势是变薄。把更多的事情交给程序去做,而不是runtime和驱动。

程序意图驱动,执行效率更高。

D3D12和Vulkan等新一代图形API的出现,响应了这一趋势,使程序能够更有效地利用硬件资源,从而提高执行效率。API去猜。这个改进的结果就是执行效率更多。这几年出现的D3D12和Vulkan,都是响应了这个趋势。

API抽象与效率优化

将不同的API抽象成同一个接口,消除了新API使用麻烦的缺点,同时保留了其效率优势。该抽象层简化了开发过程,无需关注底层细节,避免了繁琐的驱动编写,简化了代码编写,提高了易用性和开发效率。API,显得更底层,而用它们来开发更像是在写驱动,要做大量的细节操作。还好,一般来说API往上还有个渲染引擎的抽象层。可以把不同API抽象成同样的接口,这就把新API使用麻烦的缺点抹平了,同时获得新API带来的效率优势。

GPU 执行由驱动发来的操作,而驱动由 GPU 厂商提供。GPU 支持的 API 及其功能取决于驱动程序。因此,GPU 支持的 API 和功能由驱动程序决定。GPU执行的是驱动发来的操作,并不知道来自于哪个API,所谓的GPU支持哪个API。其实指的是GPU厂商提供了哪个API的驱动。所以说,GPU支持什么API的什么功能,都取决于驱动。

精简优化后的文章内容:

尽管 NVIDIA GeForce 6800 硬件缺少对 32 位浮点混合的原生支持,但其 OpenGL 驱动声称支持该功能。当应用程序使用时,驱动切换到纯软件实现,模拟执行浮点混合。这种方法有效,但效率低下,导致性能大幅下降。NVIDIA GeForce 6800硬件并不支持32位浮点混合,但它的OpenGL驱动说支持。当程序用到这个功能的时候,驱动切换到软件模式,模拟实现浮点混合。这没有任何问题,仍然是个有效的实现,只是效率有严重损失。

API,在不同操作系统上,驱动也完全不一样的。

换一个操作系统就得重写一次驱动。

精简优化版:

跨平台图形 API 驱动兼容性

不同平台对图形 API 具有不同的驱动。例如,高通在 Android 上支持 OpenGL ES,而在 Windows 上支持 D3D。因此,跨平台图形应用程序需要针对不同平台编写不同的驱动。Adreno GPU,在Android上支持OpenGL ES,而在Windows上支持D3D,就是因为它们在不同平台提供了不同的驱动。并不能因为在Android上支持OpenGL ES,这一点上,很多自以为是的人都翻过车。

模块化设计,接口隔离,上层无需了解下层实现。

ANGLE:Windows上常用的OpenGL ES实现,不依赖DDI。API不一定总是要往下到达DDI,比如ANGLE是个在Windows上最常用的OpenGL ES实现。

跨平台图形 API 库,兼容 OpenGL ES、D3D11、OpenGL、Vulkan 等,简化图形编程。OpenGL ES翻译成,D3D11、OpenGL、Vulkan这些。

这样就能在不改操作系统和驱动的情况下

跨平台图形 API 支持

- 支持 OpenGL ES。

- 支持 MoltenVK,将 Vulkan 翻译成 Metal。OpenGL ES的支持。同类的还有MoltenVK,把Vulkan翻译成Metal。

标题:突破平台限制,D3D11on12赋能新可能

D3D11on12并非简单添加翻译层,而是以D3D12实现D3D11的UMD,突破苹果平台Vulkan支持缺失的限制。Vulkan的问题。还有更奇葩的D3D11on12。它不是在上面加一个翻译层,而是用D3D12实现了一个D3D11的UMD。

跨 API 转换,兼容新旧技术

程序调用 D3D11 运行时,UMD 将其转换为 D3D12 API,实现不同 API 之间的无缝衔接。D3D11 runtime,但到了UMD之后往上返回到D3D12 API,再往下走。

* 革命性的GPU软件

* 直接在CPU上运行

* 无需昂贵的GPU硬件

* 更快的速度和更高的效率

* 为您的项目节省时间和金钱GPU。这样的驱动并不连到GPU硬件,而是在CPU上做了所有的事情。

Mesa就内置了一个软件模拟的驱动。

D3D也有一个,叫做WARP。

注意别和上一期说的GPU线程的warp搞混了,是完全不同的东西,

CPU模拟GPU,可以辅助软硬件开发调试。

- 软件模拟新功能,便于定义细节并作为硬件设计的参考。

- 无需硬件即可运行 GPU 程序,弥补缺失的 GPU。:作为硬件设计的参考。在没有安装GPU的服务器上,这样的软件模拟也可以临时用来跑一些GPU程序。

GPU和云GPU的途径。

那么,程序调用了图形API,走完整个栈,让GPU渲染之后,就直接写入帧缓存吗?

?如何保证不冲突?

这里还有一个往往被忽略的东西,叫做合成器,compositor。

在不同系统上有不同组件来充当这个角色

Windows上是DWM,Android上是SurfaceFlinger。

compositor拿到之后,

再次调用图形API,把它们合成到帧缓存,送去显示。

这叫做窗口模式,每个程序有自己的窗口,所有程序共存于桌面。

有的游戏会启用全屏独占模式,性能高一点点,

就是因为绕过了compositor,直接到达帧缓存。

Compositor 技术保证各个窗口可以独立显示,解决了独占显示导致输入法等程序无法正常显示的问题,让操作系统更加稳定可靠。Compositor在各个操作系统里都对程序透明,

* Compositor:图形软件栈的幕后英雄。

* 默默无闻,但意义非凡。

* 使图形界面流畅、协调。

* 优化系统性能,提升用户体验。compositor的。但在系统中,compositor的意义是肉眼可见的。

GPU软硬栈解析

第一期着重介绍了GPU软硬栈的整体结构,从框架API开始到硬件驱动。这些都是一些比较抽象的概念,难以直观感知。从下一期开始,我们将深入研究GPU图形流水线中的具体细节,比如光栅化等,让读者对GPU有更深入的理解。上的毛玻璃窗体、macOS上的窗口动画特效这些,也都是compositor进行的渲染。至此,GPU的软硬栈已经补全,我们看到了从上到下的整条通路。下一期将来看GPU图形流水线里的一些细节。尤其是光栅化这个操作。

-对此,您有什么看法见解?-

-欢迎在评论区留言探讨和分享。-

1 阅读:39
评论列表

薪科技快评

简介:薪科技评说,发现技术的点滴,记录科学的飞跃!