区块链技术博客
www.b2bchain.cn

同步CPU和GPU的工作求职学习资料

本文介绍了同步CPU和GPU的工作求职学习资料,有助于帮助完成毕业设计以及求职,是一篇很好的资料。

对技术面试,学习经验等有一些体会,在此分享。

Synchronizing CPU and GPU Work | Apple Developer Documentation

通过使用同一个资源的多个实例,避免CPU和GPU之间工作停滞。

本文通过一个示例展示了如何对同一资源,利用缓冲区+队列管理,让CPU和GPU同时工作,避免因资源访问的停滞。

翻译术语表

概述

在这个示例代中,你将学习如何管理数据依赖,并避免CPU和GPU之间的停滞(processor stalls)。

该项目沿着正弦波连续渲染三角形。在每一帧中,该示例都会更新每个三角形顶点都的位置,然后渲染新的图像。这些动态数据更新创造了一种运动的错觉,其中三角形似乎沿着正弦波移动。

同步CPU和GPU的工作

该示例将三角形顶点存储在CPU和GPU共享的缓冲区中。CPU向缓冲区写入数据,GPU读取数据。

注意

Xcode项目包含了在macOS、iOS和tvOS上运行该示例的方案。在iOS或tvOS模拟器中不支持Metal;要运行本示例,需要对应的iOS和Apple TV设备。默认方案是macOS,可以在Mac上运行示例。

理解数据依赖和处理器停滞的解决方案

资源共享在处理器之间产生了数据依赖(data dependency);CPU必须在GPU读取资源之前完成对资源的写入。如果GPU在CPU写入资源之前读取资源,GPU读取的是未定义的资源数据。如果GPU在CPU向其写入数据中读取资源,GPU读取的资源数据是不正确的。

同步CPU和GPU的工作

这些数据依赖在CPU和GPU之间产生了处理器停滞;每个处理器必须等待另一个处理器完成其工作后才能开始自己的工作。

然而,由于CPU和GPU是独立的处理器,你可以通过使用一个资源的多个实例让它们同时工作。对于每一帧,你必须向你的着色器提供相同的参数,但这并不意味着你需要引用同一个资源实例。相反,你可以创建一个资源的多个实例池,并在每次渲染一帧时使用不同的实例。例如,如下图所示,CPU可以将顶点位置数据写入用于n+1帧的缓冲区,同时GPU从用于n帧的缓冲区读取顶点位置数据。通过使用缓冲区的多个实例,CPU和GPU可以连续工作,只要你继续渲染帧,就可以避免停滞。

同步CPU和GPU的工作

用CPU初始化数据

定义表示顶点的自定义AAPLVertex结构体。每个顶点都有一个位置和颜色信息:

typedef struct {     vector_float2 position;     vector_float4 color; } AAPLVertex;

定义AAPLTriangle类,提供一个默认三角形接口:

+(const AAPLVertex *)vertices {     const float TriangleSize = 64;     static const AAPLVertex triangleVertices[] =     {         // Pixel Positions,                          RGBA colors.         { { -0.5*TriangleSize, -0.5*TriangleSize },  { 1, 1, 1, 1 } },         { {  0.0*TriangleSize, +0.5*TriangleSize },  { 1, 1, 1, 1 } },         { { +0.5*TriangleSize, -0.5*TriangleSize },  { 1, 1, 1, 1 } }     };     return triangleVertices; }

用位置和颜色初始化多个三角形顶点,并将它们存储在一个三角形数组_triangles中:

NSMutableArray *triangles = [[NSMutableArray alloc] initWithCapacity:NumTriangles];  // Initialize each triangle. for(NSUInteger t = 0; t < NumTriangles; t++) {     vector_float2 trianglePosition;      // Determine the starting position of the triangle in a horizontal line.     trianglePosition.x = ((-((float)NumTriangles) / 2.0) + t) * horizontalSpacing;     trianglePosition.y = 0.0;      // Create the triangle, set its properties, and add it to the array.     AAPLTriangle * triangle = [AAPLTriangle new];     triangle.position = trianglePosition;     triangle.color = Colors[t % NumColors];     [triangles addObject:triangle]; } _triangles = triangles;

分配数据存储

计算三角形顶点的总存储大小。程序渲染了50个三角形,每个三角形有3个顶点,共计150个顶点,每个顶点是AAPLVertex的大小:

const NSUInteger triangleVertexCount = [AAPLTriangle vertexCount]; _totalVertexCount = triangleVertexCount * _triangles.count; const NSUInteger triangleVertexBufferSize = _totalVertexCount * sizeof(AAPLVertex);

初始化多个缓冲区来储存顶点数据的多个副本。对于每个缓冲区,分配的内存正好足够存储150个顶点:

for(NSUInteger bufferIndex = 0; bufferIndex < MaxFramesInFlight; bufferIndex++) {     _vertexBuffers[bufferIndex] = [_device newBufferWithLength:triangleVertexBufferSize                                                        options:MTLResourceStorageModeShared];     _vertexBuffers[bufferIndex].label = [NSString stringWithFormat:@"Vertex Buffer #%lu", (unsigned long)bufferIndex]; }

初始化后,_vertexBuffers数组中的缓冲区实例内容为空。

用CPU更新数据

在每一帧中,在drawInMTKView:渲染循环的开始,使用CPU在updateState方法中更新一个缓冲区实例的内容:

“`
// Vertex data for the current triangles.
AAPLVertex *currentTriangleVertices = _vertexBuffers[_currentBuffer].contents;

// Update each triangle.
for(NSUInteger triangle = 0; triangle < NumTriangles; triangle++)
{
vector_float2 trianglePosition = _triangles[triangle].position;

// Displace the y-position of the triangle using a sine wave. trianglePosition.y = (sin(trianglePosition.x/waveMagnitude + _wavePosition) * waveMagnitude);  // Update the position of the triangle.

Synchronizing CPU and GPU Work | Apple Developer Documentation

通过使用同一个资源的多个实例,避免CPU和GPU之间工作停滞。

本文通过一个示例展示了如何对同一资源,利用缓冲区+队列管理,让CPU和GPU同时工作,避免因资源访问的停滞。

翻译术语表

概述

在这个示例代中,你将学习如何管理数据依赖,并避免CPU和GPU之间的停滞(processor stalls)。

该项目沿着正弦波连续渲染三角形。在每一帧中,该示例都会更新每个三角形顶点都的位置,然后渲染新的图像。这些动态数据更新创造了一种运动的错觉,其中三角形似乎沿着正弦波移动。

同步CPU和GPU的工作

该示例将三角形顶点存储在CPU和GPU共享的缓冲区中。CPU向缓冲区写入数据,GPU读取数据。

注意

Xcode项目包含了在macOS、iOS和tvOS上运行该示例的方案。在iOS或tvOS模拟器中不支持Metal;要运行本示例,需要对应的iOS和Apple TV设备。默认方案是macOS,可以在Mac上运行示例。

理解数据依赖和处理器停滞的解决方案

资源共享在处理器之间产生了数据依赖(data dependency);CPU必须在GPU读取资源之前完成对资源的写入。如果GPU在CPU写入资源之前读取资源,GPU读取的是未定义的资源数据。如果GPU在CPU向其写入数据中读取资源,GPU读取的资源数据是不正确的。

同步CPU和GPU的工作

这些数据依赖在CPU和GPU之间产生了处理器停滞;每个处理器必须等待另一个处理器完成其工作后才能开始自己的工作。

然而,由于CPU和GPU是独立的处理器,你可以通过使用一个资源的多个实例让它们同时工作。对于每一帧,你必须向你的着色器提供相同的参数,但这并不意味着你需要引用同一个资源实例。相反,你可以创建一个资源的多个实例池,并在每次渲染一帧时使用不同的实例。例如,如下图所示,CPU可以将顶点位置数据写入用于n+1帧的缓冲区,同时GPU从用于n帧的缓冲区读取顶点位置数据。通过使用缓冲区的多个实例,CPU和GPU可以连续工作,只要你继续渲染帧,就可以避免停滞。

同步CPU和GPU的工作

用CPU初始化数据

定义表示顶点的自定义AAPLVertex结构体。每个顶点都有一个位置和颜色信息:

typedef struct {     vector_float2 position;     vector_float4 color; } AAPLVertex;

定义AAPLTriangle类,提供一个默认三角形接口:

+(const AAPLVertex *)vertices {     const float TriangleSize = 64;     static const AAPLVertex triangleVertices[] =     {         // Pixel Positions,                          RGBA colors.         { { -0.5*TriangleSize, -0.5*TriangleSize },  { 1, 1, 1, 1 } },         { {  0.0*TriangleSize, +0.5*TriangleSize },  { 1, 1, 1, 1 } },         { { +0.5*TriangleSize, -0.5*TriangleSize },  { 1, 1, 1, 1 } }     };     return triangleVertices; }

用位置和颜色初始化多个三角形顶点,并将它们存储在一个三角形数组_triangles中:

NSMutableArray *triangles = [[NSMutableArray alloc] initWithCapacity:NumTriangles];  // Initialize each triangle. for(NSUInteger t = 0; t < NumTriangles; t++) {     vector_float2 trianglePosition;      // Determine the starting position of the triangle in a horizontal line.     trianglePosition.x = ((-((float)NumTriangles) / 2.0) + t) * horizontalSpacing;     trianglePosition.y = 0.0;      // Create the triangle, set its properties, and add it to the array.     AAPLTriangle * triangle = [AAPLTriangle new];     triangle.position = trianglePosition;     triangle.color = Colors[t % NumColors];     [triangles addObject:triangle]; } _triangles = triangles;

分配数据存储

计算三角形顶点的总存储大小。程序渲染了50个三角形,每个三角形有3个顶点,共计150个顶点,每个顶点是AAPLVertex的大小:

const NSUInteger triangleVertexCount = [AAPLTriangle vertexCount]; _totalVertexCount = triangleVertexCount * _triangles.count; const NSUInteger triangleVertexBufferSize = _totalVertexCount * sizeof(AAPLVertex);

初始化多个缓冲区来储存顶点数据的多个副本。对于每个缓冲区,分配的内存正好足够存储150个顶点:

for(NSUInteger bufferIndex = 0; bufferIndex < MaxFramesInFlight; bufferIndex++) {     _vertexBuffers[bufferIndex] = [_device newBufferWithLength:triangleVertexBufferSize                                                        options:MTLResourceStorageModeShared];     _vertexBuffers[bufferIndex].label = [NSString stringWithFormat:@"Vertex Buffer #%lu", (unsigned long)bufferIndex]; }

初始化后,_vertexBuffers数组中的缓冲区实例内容为空。

用CPU更新数据

在每一帧中,在drawInMTKView:渲染循环的开始,使用CPU在updateState方法中更新一个缓冲区实例的内容:

“`
// Vertex data for the current triangles.
AAPLVertex *currentTriangleVertices = _vertexBuffers[_currentBuffer].contents;

// Update each triangle.
for(NSUInteger triangle = 0; triangle < NumTriangles; triangle++)
{
vector_float2 trianglePosition = _triangles[triangle].position;

// Displace the y-position of the triangle using a sine wave. trianglePosition.y = (sin(trianglePosition.x/waveMagnitude + _wavePosition) * waveMagnitude);  // Update the position of the triangle.

Synchronizing CPU and GPU Work | Apple Developer Documentation

通过使用同一个资源的多个实例,避免CPU和GPU之间工作停滞。

本文通过一个示例展示了如何对同一资源,利用缓冲区+队列管理,让CPU和GPU同时工作,避免因资源访问的停滞。

翻译术语表

概述

在这个示例代中,你将学习如何管理数据依赖,并避免CPU和GPU之间的停滞(processor stalls)。

该项目沿着正弦波连续渲染三角形。在每一帧中,该示例都会更新每个三角形顶点都的位置,然后渲染新的图像。这些动态数据更新创造了一种运动的错觉,其中三角形似乎沿着正弦波移动。

同步CPU和GPU的工作

该示例将三角形顶点存储在CPU和GPU共享的缓冲区中。CPU向缓冲区写入数据,GPU读取数据。

注意

Xcode项目包含了在macOS、iOS和tvOS上运行该示例的方案。在iOS或tvOS模拟器中不支持Metal;要运行本示例,需要对应的iOS和Apple TV设备。默认方案是macOS,可以在Mac上运行示例。

理解数据依赖和处理器停滞的解决方案

资源共享在处理器之间产生了数据依赖(data dependency);CPU必须在GPU读取资源之前完成对资源的写入。如果GPU在CPU写入资源之前读取资源,GPU读取的是未定义的资源数据。如果GPU在CPU向其写入数据中读取资源,GPU读取的资源数据是不正确的。

同步CPU和GPU的工作

这些数据依赖在CPU和GPU之间产生了处理器停滞;每个处理器必须等待另一个处理器完成其工作后才能开始自己的工作。

然而,由于CPU和GPU是独立的处理器,你可以通过使用一个资源的多个实例让它们同时工作。对于每一帧,你必须向你的着色器提供相同的参数,但这并不意味着你需要引用同一个资源实例。相反,你可以创建一个资源的多个实例池,并在每次渲染一帧时使用不同的实例。例如,如下图所示,CPU可以将顶点位置数据写入用于n+1帧的缓冲区,同时GPU从用于n帧的缓冲区读取顶点位置数据。通过使用缓冲区的多个实例,CPU和GPU可以连续工作,只要你继续渲染帧,就可以避免停滞。

同步CPU和GPU的工作

用CPU初始化数据

定义表示顶点的自定义AAPLVertex结构体。每个顶点都有一个位置和颜色信息:

typedef struct {     vector_float2 position;     vector_float4 color; } AAPLVertex;

定义AAPLTriangle类,提供一个默认三角形接口:

+(const AAPLVertex *)vertices {     const float TriangleSize = 64;     static const AAPLVertex triangleVertices[] =     {         // Pixel Positions,                          RGBA colors.         { { -0.5*TriangleSize, -0.5*TriangleSize },  { 1, 1, 1, 1 } },         { {  0.0*TriangleSize, +0.5*TriangleSize },  { 1, 1, 1, 1 } },         { { +0.5*TriangleSize, -0.5*TriangleSize },  { 1, 1, 1, 1 } }     };     return triangleVertices; }

用位置和颜色初始化多个三角形顶点,并将它们存储在一个三角形数组_triangles中:

NSMutableArray *triangles = [[NSMutableArray alloc] initWithCapacity:NumTriangles];  // Initialize each triangle. for(NSUInteger t = 0; t < NumTriangles; t++) {     vector_float2 trianglePosition;      // Determine the starting position of the triangle in a horizontal line.     trianglePosition.x = ((-((float)NumTriangles) / 2.0) + t) * horizontalSpacing;     trianglePosition.y = 0.0;      // Create the triangle, set its properties, and add it to the array.     AAPLTriangle * triangle = [AAPLTriangle new];     triangle.position = trianglePosition;     triangle.color = Colors[t % NumColors];     [triangles addObject:triangle]; } _triangles = triangles;

分配数据存储

计算三角形顶点的总存储大小。程序渲染了50个三角形,每个三角形有3个顶点,共计150个顶点,每个顶点是AAPLVertex的大小:

const NSUInteger triangleVertexCount = [AAPLTriangle vertexCount]; _totalVertexCount = triangleVertexCount * _triangles.count; const NSUInteger triangleVertexBufferSize = _totalVertexCount * sizeof(AAPLVertex);

初始化多个缓冲区来储存顶点数据的多个副本。对于每个缓冲区,分配的内存正好足够存储150个顶点:

for(NSUInteger bufferIndex = 0; bufferIndex < MaxFramesInFlight; bufferIndex++) {     _vertexBuffers[bufferIndex] = [_device newBufferWithLength:triangleVertexBufferSize                                                        options:MTLResourceStorageModeShared];     _vertexBuffers[bufferIndex].label = [NSString stringWithFormat:@"Vertex Buffer #%lu", (unsigned long)bufferIndex]; }

初始化后,_vertexBuffers数组中的缓冲区实例内容为空。

用CPU更新数据

在每一帧中,在drawInMTKView:渲染循环的开始,使用CPU在updateState方法中更新一个缓冲区实例的内容:

“`
// Vertex data for the current triangles.
AAPLVertex *currentTriangleVertices = _vertexBuffers[_currentBuffer].contents;

// Update each triangle.
for(NSUInteger triangle = 0; triangle < NumTriangles; triangle++)
{
vector_float2 trianglePosition = _triangles[triangle].position;

// Displace the y-position of the triangle using a sine wave. trianglePosition.y = (sin(trianglePosition.x/waveMagnitude + _wavePosition) * waveMagnitude);  // Update the position of the triangle.

部分转自互联网,侵权删除联系

赞(0) 打赏
部分文章转自网络,侵权联系删除b2bchain区块链学习技术社区 » 同步CPU和GPU的工作求职学习资料
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址

b2b链

联系我们联系我们