美文网首页
iOS Metal CPU与GPU同步

iOS Metal CPU与GPU同步

作者: 雄关漫道从头越 | 来源:发表于2019-07-17 15:59 被阅读0次

Metal框架详细解析(二十三) —— 基本课程之CPU和GPU同步(三)

CPU and GPU Synchronization - CPU和GPU同步

演示如何更新缓冲区数据并同步CPU和GPU之间的访问。

在此示例中,您将学习如何正确更新和渲染CPU与图形处理单元(GPU)之间共享的动画资源。 特别是,您将学习如何修改每帧数据,避免数据访问危险,并且并行执行CPU和GPU工作。


CPU/GPU Parallelism and Shared Resource Access - CPU / GPU并行和共享资源访问

CPU和GPU是独立的异步处理器。在Metal应用程序或游戏中,CPU对命令进行编码,GPU执行命令。在每个帧中重复该序列,并且当CPU和GPU都完成其工作时完成全帧的工作。 CPU和GPU可以并行工作,无需等待彼此完成工作。例如,GPU可以执行帧1的命令,而CPU对帧2的命令进行编码。

这种CPU / GPU并行性对于您的Metal应用程序或游戏具有很大的优势,有效地使您可以同时在两个处理器上运行。但是,这些处理器仍然可以协同工作,并且通常可以访问相同的共享资源,例如顶点缓冲区或片段纹理。必须小心处理共享资源访问;否则,CPU和GPU可能同时访问共享资源,从而导致竞争条件和数据损坏。

与大多数Metal应用或游戏一样,此示例通过更新每个帧中的顶点数据来渲染动画内容。请考虑以下顺序:

  • 1) 渲染循环启动一个新帧。
  • 2) CPU将新顶点数据写入顶点缓冲区。
  • 3) CPU对渲染命令进行编码并提交命令缓冲区。
  • 4) GPU开始执行命令缓冲区。
  • 5) GPU从顶点缓冲区读取顶点数据。
  • 6) GPU将像素渲染到drawable。
  • 7) 渲染循环完成帧。

在此序列中,CPU和GPU共享一个顶点缓冲区。 如果处理器在开始自己的工作之前等待彼此完成工作,则共享顶点缓冲区没有访问冲突。 此模型避免了访问冲突,但浪费了宝贵的处理时间:当一个处理器正在工作时,另一个处理器处于空闲状态。

Metal旨在最大化CPU和GPU并行性,因此这些处理器应该保持忙碌并且应该同时工作。 理想情况下,GPU应该读取帧1的顶点数据,而CPU正在为帧2写入顶点数据。但是,共享单个顶点缓冲区意味着CPU可以在GPU读取之前覆盖前一帧的顶点数据,从而导致难看的渲染效果。

为了减少处理器空闲时间并避免访问冲突,可以使用多个缓冲区而不是单个缓冲区来共享顶点数据。 例如,CPU和GPU可以共享帧1的顶点缓冲区1,帧2的顶点缓冲区2,帧3的顶点缓冲区3,等等。 在此模型中,共享顶点数据在每个帧中保持一致,并且处理器同时访问不同的顶点缓冲区。


Implement a Triple Buffer Model - 实现三重缓冲模型

此示例呈现数百个小四边形,也称为sprites。要为精灵设置动画,样本会在每个帧的开头更新它们的位置,并将它们写入顶点缓冲区。帧完成后,CPU和GPU不再需要该帧的顶点缓冲区。丢弃使用过的顶点缓冲区并为每个帧创建一个新的顶点缓冲区是浪费的。相反,可以使用可重用顶点缓冲区的FIFO队列实现更可持续的模型。

队列中的最大缓冲区数由MaxBuffersInFlight的值定义,设置为3。此常量值定义设备的任何部分可以同时处理的最大帧数;这包括应用程序,驱动程序或显示。该应用程序仅适用于CPU或GPU中的框架,但OS本身可以在驱动程序或显示级别的框架上工作。使用三个缓冲区可为设备提供足够的余地,以便高效且有效地工作。缓冲区太少会导致处理器停顿和资源争用,而缓冲区太多会导致内存开销和帧延迟增加。

for(NSUInteger bufferIndex = 0; bufferIndex < MaxBuffersInFlight; bufferIndex++)
{
    _vertexBuffers[bufferIndex] = [_device newBufferWithLength:spriteVertexBufferSize
                                                       options:MTLResourceStorageModeShared];
}

drawInMTKView:渲染循环开始时,示例遍历_vertexBuffer数组中的每个缓冲区,每帧只更新一个缓冲区。 在每三个帧结束时,在使用所有三个缓冲区之后,样本循环回到数组的开始并更新_vertexBuffer [0]缓冲区的内容。


Manage the Rate of Work - 管理工作率

为避免过早覆盖数据,样本必须确保GPU在重新使用之前已处理缓冲区的内容。 否则,CPU可能会覆盖先前三帧写入但尚未被GPU读取的顶点数据。 当CPU为GPU生成工作的速度超过GPU完成工作时,就会出现这种情况。

如果CPU在GPU之前运行得太远,则此示例使用信号量等待全帧完成。

_inFlightSemaphore = dispatch_semaphore_create(MaxBuffersInFlight);

在渲染循环开始时,信号量检查进行或等待信号。 如果可以使用或重用缓冲区,则CPU工作继续进行;否则,它等待缓冲区可用。

dispatch_semaphore_wait(_inFlightSemaphore, DISPATCH_TIME_FOREVER);

GPU无法直接发信号通知信号,但它可以向CPU发出完成回调。

[commandBuffer addCompletedHandler:^(id<MTLCommandBuffer> buffer)
{
    dispatch_semaphore_signal(block_sema);
}];

addCompletedHandler:方法注册在GPU完成命令缓冲区后立即调用的代码块。 此命令缓冲区与为帧提交顶点缓冲区的命令缓冲区相同,因此接收完成回调指示可以安全地重用顶点缓冲区。

相关文章

  • iOS Metal CPU与GPU同步

    Metal框架详细解析(二十三) —— 基本课程之CPU和GPU同步(三) CPU and GPU Synchro...

  • 02-iOS 平台下 Metal 框架

    什么是Metal?Metal 与 OpenGL ES 区别?CPU/GPU 迭代 Metal 的表现 Metal ...

  • iOS开发中的CPU渲染

    CPU发出绘制指令,GPU执行绘制指令。CPU通过OpenGL/Metal给GPU发送各种绘制指令,同时把自己的内...

  • iOS性能优化

    屏幕呈像 iOS的屏幕成像中,CPU,GPU起着关键作用,屏幕的卡顿与CPU对数据的计算,GPU的渲染,屏幕的刷新...

  • 浅谈 iOS 性能优化

    iOS 中的 CPU 和 GPU 在屏幕成像过程中,CPU 和 GPU 起着很重要的作用。 CPU(Central...

  • Apple Metal 2 6.CPU和GPU 同步

    原文https://developer.apple.com/documentation/metal/fundame...

  • 初识Metal

    Metal Metal 是一个和 OpenGL ES类似的面向底层的图形编程接口,可以直接操作GPU;并在iOS,...

  • 底层原理(十)------性能优化

    CPU和GPU 屏幕成像原理 卡顿产生的原因 如果CPU跟GPU处理的时间刚好到垂直同步信号,则屏幕成像如果CPU...

  • 性能优化02-布局优化

    性能优化02-布局优化 一、CPU与GPU 1、定义 为什么要了解CPU与GPU呢?因为布局绘制就是CPU与GPU...

  • 初识MetalView

    Metal metal是iOS设备的一个底层图形API,功能类似OpenGL,支持图形渲染和GPU通用计算.met...

网友评论

      本文标题:iOS Metal CPU与GPU同步

      本文链接:https://www.haomeiwen.com/subject/gqxclctx.html