您的位置:首页 > 移动开发 > IOS开发

Metal-IOS-通用GPU计算:Data-Parallel Compute Processing: Compute Command Encoder

2016-02-18 10:43 246 查看


原文:Data-Parallel Compute Processing: Compute Command
Encoder

数据并行处理:‘计算机命令编码器’

相关连接:

1.GPU:并行计算利器

2.Metal:对 iOS 中 GPU 编程的高度优化的框架

3.聊聊GPU通用计算

4.OpenGL实现通用GPU计算概述

译文:

一、数据并行处理的计算的步奏

这个章节解释了如何创建并使用一个MTLComputeCommandEncoder对象去编译‘数据并行处理状态和命令’,并提交设备上执行。

要执行‘数据并行处理的计算’,按照以下步奏:

1.使用一个MTLDevice的方法去创建一个‘计算机状态’(MTLComputePipelineState),即包含编译后的MTLFunction对象,在创建‘计算机状态’的过程中(as
discussed in Creating a Compute State)作为一个需要‘处理、讨论’的对象。MTLFunction对象代表了一个用于写‘Metal shading language’的计算机函数,作为函数和函数库的描述。

2.指定MTLComputePipelineState对象使用,是通过‘计算命令编译器’完成的,并为一个‘计算命令编译器’指定一个计算状态和资源用于‘处理、讨论’(as discussed in Specifying a Compute State and Resources for a Compute Command Encoder.)

3.指定资源和相关对象(MTLBuffer ,MTLTexture,或者MTLSamplerState),可能包含‘计算机状态(compute state)’需要处理和返回的数据,并为一个‘计算命令编译器’指定一个计算状态和资源用于‘处理、讨论’。此外还设置参数索引表,使的‘Metal framework’在‘着色器代码(shader
code)’中可以定位相应的资源。在任何给定的时刻,MTLComputeCommandEncoder可以联系到很多资源对象

4.调度‘计算机函数(compute function)’执行指定的次数,即如前所说的‘执行一个计算机命令(Executing a Compute Command)’。

二、创建一个计算管道的状态

2.1 一个MTLFunction对象即‘数据并行代码(data-parallel code)’,是可以被MTLComputePipelineState对象执行的。MTLComputeCommandEncoder对象的编译命令只要是设置参数和执行‘计算机函数’。由于创建一个‘计算机管道状态(compute
pipeline state)’会耗费较大时间在编译‘Metal shading language code’上面,所以你需要使用异步的方式(比如‘blocking’或者‘asynchronous’),来安排时间/逻辑,使之最适合你的App。

2.2 同步创建计算管道状态对象,要么调用MTLDevice的‘newComputePipelineStateWithFunction:error:’,或者调用‘newComputePipelineStateWithFunction:options:reflection:error:’。在‘Metal’编译着色器代码去创建管道状态对象时,这些方法将阻塞当前线程。

2.3 异步创建计算管道状态对象,要么调用MTLDevice的‘newComputePipelineStateWithFunction:completionHandler:’,或者调用‘newComputePipelineStateWithFunction:options:completionHandler:’。这些方法会立即返回:‘Metal’
会异步编译着色器代码去创建’管道状态‘对象,创建完成后会调用‘completionhandler’来提供新的MTLComputePipelineState对象。

2.4 当你创建一个MTLComputePipelineState对象时,你也可以选择创建‘反射数据(reflection data)’,用来揭示了计算函数及其参数的细节。‘newComputePipelineStateWithFunction:options:reflection:error:’和‘newComputePipelineStateWithFunction:options:completionHandler:’提供这些数据。避免获取反射数据如果它不会被使用。如果想知道更多关于‘反射数据’的资料,在这里:Determining
Function Details at Runtime。

三、为‘计算命令编译器’指定一个计算状态和资源

3.1 对象MTLComputeCommandEncoder的函数‘setComputePipelineState: ’指定了状态,包括编译‘计算着色器函数’,用来使‘数据并行计算(data-parallel compute)’:通过/运行。在任何给定的时刻,一个‘计算命令编译器’仅能联系到一个计算函数

3.2 下面的‘’方法指定了一个资源(如:一个缓冲区,纹理,取样器状态,或threadgroup内存)作为参数使用,对MTLComputePipelineState对象所代表的计算函数。如下:

setBuffer:offset:atIndex:

setBuffers:offsets:withRange:

setTexture:atIndex:

setTextures:withRange:

setSamplerState:atIndex:

setSamplerState:lodMinClamp:lodMaxClamp:atIndex:

setSamplerStates:withRange:

setSamplerStates:lodMinClamps:lodMaxClamps:withRange:

setThreadgroupMemoryLength:atIndex:

每个方法分配一个或多个资源对应的参数,如图6 - 1所示

Figure 6-1 Argument Tables for the Compute Command Encoder



有31项的最大缓冲区参数表,31个纹理参数表中的条目,和16个采样器状态参数表中的条目。所有threadgroup内存分配的总额不得超过16 KB;否则,发生错误。

四、执行计算的命令

编译一个命令来执行一个计算函数,调用MTLComputeCommandEncoder的方法‘dispatchThreadgroups:threadsPerThreadgroup: ’,并且指定threadgroup维度和threadgroup的数量。你可以查询‘threadExecutionWidth’和‘maxTotalThreadsPerThreadgroup’等MTLComputePipelineState的属性,由此优化在这个‘device’的计算函数的执行。

最有效的执行计算函数,是通过设置指定线程总数,即函数‘dispatchThreadgroups:threadsPerThreadgroup’的‘threadsPerThreadgroup’这个参数,使得‘threadExecutionWidth’具有‘多样性/多值’。‘threadgroup’里的线程总数为(threadsPerThreadgroup):threadsPerThreadgroup.width
* threadsPerThreadgroup.height *threadsPerThreadgroup.depth
。属性‘maxTotalThreadsPerThreadgroup’指定了‘device’在‘单个线程组’能执行的计算函数的最大数量

计算命令是按照‘命令’存入命令缓冲区的顺序去执行的。只有当所有相关的‘’命令执行完成并且所有的结果写入内存时,才叫‘执行完一条计算命令’。由于这种排序,当计算命令结果在命令缓冲区时可以用于任何命令编译。

调用MTLComputeCommandEncoder的方法:endEncoding 使‘计算命令编译器’结束‘编译命令’。当前面的’命令编译器‘结束后,你才可以’新创建’一个任意类型的‘命令编译器’,去编码额外的命令到‘命令缓冲区’。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: