Metal 执行 GPU 命令的流程
概述
阅读完本文,你将了解 Metal 是如何在 GPU 上执行命令的。
让 GPU 来执行任务是通过发送命令来实现的。 该命令可以执行绘图、并行计算或资源管理相关的操作工作。
Metal 应用程序和 GPU 之间的关系是客户端-服务器模式:
- Metal 应用程序是客户端
- GPU 是服务器
- 可以通过向 GPU 发送命令来发出请求
- 处理完命令后,GPU 通知应用空闲状态
下图为 Metal 客户端-服务器模式
要将命令发送到 GPU,可以使用命令编码器对象将它们添加到命令缓冲区。
将命令缓冲区添加到命令队列,然后提交命令缓冲区来让 Metal 执行命令缓冲区的命令。
入队和提交命令缓冲区中放置命令的顺序很重要,因为它会影响 Metal 执行命令的顺序。
以下部分涵盖了设置工作命令结构的步骤,这些步骤按照创建与 Metal 交互的对象的方式进来组织。
生成初始化时的对象
在初始化时创建的一些 Metal 对象,通常会无限期地保留它们。创建命令队列和管道对象的成本很高,只需要初始化一次,后续就可以复用它们。
创建命令队列
通过调用 makeCommandQueue() 函数来创建命令队列:
swift commandQueue = device.makeCommandQueue()
需要创建一个强引用对象来指向命令队列,命令队列是用来保存命令缓冲区的,如下所示:
创建一个或多个管道对象
管道对象封装了 Metal 着色语言编写的函数,告诉 Metal 如何处理命令。
以下是管道处理 Metal 工作流程:
- 编写处理数据的 Metal 着色器函数
- 创建一个包含着色器的管道对象
- 启用管道
- 绘制、计算或 blit 调用
Metal 不会立即执行绘制、计算或 blit 调用;相反,可以使用编码器对象将这些调用的命令封装起来,然后插入到命令缓冲区中。提交命令缓冲区后,Metal 将其发送到 GPU 并使用激活的管道对象来处理命令。
向 GPU 发出命令
准备好命令队列和管道后,就可以向 GPU 发出命令了。具体流程如下:
- 创建命令缓冲区
- 用命令填充缓冲区
- 将命令缓冲区提交给 GPU
如果将动画作为渲染循环的一部分执行,则对动画的每一帧都执行此操作。还可以按照此过程执行一次性图像处理或机器学习任务。
创建命令缓冲区
在命令队列上调用 makeCommandBuffer() 来创建命令缓冲区。
swift guard let commandBuffer = commandQueue.makeCommandBuffer() else { return }
对于单线程应用程序,可以创建一个命令缓冲区。如下显示了命令与其命令缓冲区之间的关系:
将命令添加到命令缓冲区
当在编码器对象上调用特定于任务的函数时(例如绘制、计算或 blit 操作),编码器会将这些调用的命令放入命令缓冲区。编码器对命令进行编码以包含 GPU 在运行时处理任务所需的一切。如下显示了命令编码器将命令插入命令缓冲区作为渲染结果工作流程:
具体取决于不同的任务 可以使用 MTLCommandEncoder 的具体子类对实际命令进行编码: - 使用 MTLRenderCommandEncoder 发出渲染命令 - 使用 MTLComputeCommandEncoder 发出并行计算命令 - 使用 MTLBlitCommandEncoder 发出资源管理命令
提交渲染缓冲区
为了运行命令,需要将命令缓冲区提交给 GPU:
swift commandBuffer.commit()
提交命令缓冲区不会立即运行其命令。相反,Metal 按照队列中优先级来处理缓冲区中的命令。如果没有显示地将命令缓冲区入队,一旦提交到缓冲区,Metal 就会执行此操作。
Metal 所遵循的规则是命令执行的顺序与添加它们的顺序相同。虽然 Metal 可能会在处理某些命令之前对它们进行重新排序,但这通常只发生在性能提升且没有其他可影响的情况下。
总结
本文介绍了 Metal 在 GPU 上执行命令的流程。Metal 执行任务是通过发送 GPU 命令来完成的,它们之间的关系是客户端-服务器模式。执行的命令需要添加到命令缓冲区中,命令缓冲区再加入到命令队列中,最后按照顺序依次提交到 GPU 来处理。
Metal 执行 GPU 命令的流程相关推荐
- 从Java执行可执行的命令行
在本文中,我们将介绍Java开发人员的常见需求. 从Java内部执行和管理外部流程. 由于这项任务很常见,因此我们着手寻找一个Java库来帮助我们完成它. 该库的要求是: 异步执行该过程. 能够中止流 ...
- python执行的命令_如何在Python中执行外部命令
Python子进程模块允许生成新进程,从Python脚本执行外部命令. 您可以使用这些教程来安装最新版本的Python. 此外,还有许多可用于Python IDE. 就像在Ubuntu系统上安装PyC ...
- uboot源码分析(1)uboot 命令解析流程简析
uboot 命令解析流程简析 uboot正常启动后,会调用main_loop(void)函数,进入main_loop()之后,如果在规定的时间(CONFIG_BOOTDELAY)内,没有检查到任何按键 ...
- java执行db2命令_送你一份P6级Java面试题
导读: 作者:瞿云康,英文名jacksonKang,是一名努力成长中的Java爱好者.本文出处:http://mayiyk.cn/article/6本文为昨天Java面试题整理的第二篇,这个系列的文章 ...
- Windows中使用Java执行shell命令运行检测,通过sonarqube的webapi获取扫描结果
目录 1,实验环境 2,前言(环境配置) 3,通过Java执行shell命令扫描项目 3.1 主要思路 3.2 参考代码 3.3 运行效果 4,通过sonarqube的webapi获取项目扫描结果 4 ...
- CMake中执行shell命令之execute_process、add_custom_target和add_custom_command
背景 以下情况可能需要在CMake中执行shell脚本: cmake未提供的功能而实际构建中又需要时,如获取Linux发行版本 项目构建时需要执行脚本才能完成,如boost构建过程 有的需要shell ...
- linux命令行下写for语句,Linux命令行 – 流程控制:for 循环
在这关于流程控制的最后一章中,我们将看看另一种 shell 循环构造.for 循环不同于 while 和 until 循环,因为 在循环中,它提供了一种处理序列的方式.这在编程时非常有用.因此在 ba ...
- Docker常用命令-全流程
Docker环境安装 安装详细说明参考官方文档:https://docs.docker.com/get-docker/ 环境信息查看 ##查看docker容器版本 docker version ##查 ...
- NVMe over TCP Write/Read命令下发流程梳理
总结 本文对NVMe over TCP的write和read命令下发流程进行了梳理 1. 环境 只针对Linux5.4.0版本的nvme内核模块源代码,使用命令 sudo nvme io-passth ...
最新文章
- Session Cookies Cache 的区别
- 【原创】概率DP总结 by kuangbin
- android界面不可见键盘隐藏功能,Android中点击隐藏软键盘最佳方法
- 网络与IO知识扫盲(五):从 NIO 到多路复用器
- Build 2016,你可能忽视的几个细节
- 【C++】 67_经典问题分析 五
- How to Fix Git Push Time Consuming Issue in a Big Team?
- ais信号接收设备_基于USRP的AIS接收机实现
- _inflateEnd, referenced from _inflateInit_错误,
- uni-app 167将某人踢出群聊(二)
- 使用android studio设置签名信息
- ios html fixed,ios下position:fixed失效的问题解决
- AMADA阿玛达JAE工控机维修UT5-AMD9-B故障汇总
- 工作小妙招之将Excel中不同sheet中的数据按照相同属性进行合并
- win10系统编辑服务器在哪个文件夹,文件夹选项在哪里,小编教你Win10文件夹选项在哪...
- 2D动画设计制作软件:Cartoon Animator 中文版win/mac版
- y0usef(vulnhub)
- iOS开发 NSPredicate的使用方法
- java中将html语言转换_JAVA中将html转换成pdf
- Lync Server 2010 呼叫寄存配置和启用