Metal框架详细解析(十五) —— 计算处理之关于线程和线程组(三)

版本记录

版本号 时间
V1.0 2018.10.08 星期一

前言

很多做视频和图像的,相信对这个框架都不是很陌生,它渲染高级3D图形,并使用GPU执行数据并行计算。接下来的几篇我们就详细的解析这个框架。感兴趣的看下面几篇文章。
1. Metal框架详细解析(一)—— 基本概览
2. Metal框架详细解析(二) —— 器件和命令(一)
3. Metal框架详细解析(三) —— 渲染简单的2D三角形(一)
4. Metal框架详细解析(四) —— 关于GPU Family 4(一)
5. Metal框架详细解析(五) —— 关于GPU Family 4之关于Imageblocks(二)
6. Metal框架详细解析(六) —— 关于GPU Family 4之关于Tile Shading(三)
7. Metal框架详细解析(七) —— 关于GPU Family 4之关于光栅顺序组(四)
8. Metal框架详细解析(八) —— 关于GPU Family 4之关于增强的MSAA和Imageblock采样覆盖控制(五)
9. Metal框架详细解析(九) —— 关于GPU Family 4之关于线程组共享(六)
10. Metal框架详细解析(十) —— 基本组件(一)
11. Metal框架详细解析(十一) —— 基本组件之器件选择 - 图形渲染的器件选择(二)
12. Metal框架详细解析(十二) —— 基本组件之器件选择 - 计算处理的设备选择(三)
13. Metal框架详细解析(十三) —— 计算处理(一)
14. Metal框架详细解析(十四) —— 计算处理之你好,计算(二)

About Threads and Threadgroups - 关于线程和线程组

了解Metal如何组织计算处理工作负载。


Overview - 概览

回想一下Hello Compute,当您调度计算传递时,Metal会在1D,2D或3D网格上执行您的内核函数。 网格中的每个点代表内核函数的单个实例,称为线程。 例如,在图像处理中,网格通常是线程的2D矩阵 - 表示整个图像 - 每个线程对应于正被处理的图像的单个像素。

线程被组织成一起执行的线程组,并且可以共享公共的内存块。 虽然有时内核函数的设计使得线程彼此独立运行,但线程组中的线程在其工作集上进行协作也很常见。


Identification of Threads by Position in Grid - 按网格中的位置识别线程

图1显示了计算内核处理的图像如何划分为线程组以及每个线程组如何由各个线程组成。 每个线程处理一个像素。

Figure 1 A grid divided into threadgroups that are composed of individual threads.

线程可以通过它在网格中的位置来识别;这是一个独特的位置,允许你的内核函数为每个线程做一些不同的事情。 下面的Hello Compute中的示例内核函数显示了线程在网格中的位置如何作为参数传递给函数。 在这种情况下,参数gid是表示2D坐标的向量,用于读取和写入纹理中的特定位置。

kernel void
grayscaleKernel(texture2d<half, access::read>  inTexture  [[texture(AAPLTextureIndexInput)]],
                texture2d<half, access::write> outTexture [[texture(AAPLTextureIndexOutput)]],
                uint2                          gid        [[thread_position_in_grid]])
{
    if((gid.x >= outTexture.get_width()) || (gid.y >= outTexture.get_height()))
    {
        return;
    }
    half4 inColor  = inTexture.read(gid);
    half  gray     = dot(inColor.rgb, kRec709Luma);
    outTexture.write(half4(gray, gray, gray, 1.0), gid);
}

[[thread_position_in_grid]]是属性限定符。 可通过双方括号语法识别的属性限定符允许将内核参数绑定到资源和内置变量,在这种情况下,线程在网格中的位置对应内核函数。

例如,给定一个16 x 16线程的网格划分为2 x 4线程组的8 x 4线程,单个线程(如图2中的红色所示)在网格中的位置为(9,10)

Figure 2 The position of a single thread in a 16 x 16 grid.

Identification of Threads by Position in Threadgroup - 线程组中按位置识别线程

线程组中线程的位置也可用作属性限定符[[thread_position_in_threadgroup]],并且线程组在网格中的位置可用作[[threadgroup_position_in_grid]]

根据网格的形状,这些位置属性可以是标量值,也可以是两元素或三元素矢量。 在2D网格的情况下,位置属性是双元素向量,原点位于左上角。

图2中标识的线程位于线程组中,网格中的位置为(1,2),其在该线程组中的位置为(1,2),如图3所示:

Figure 3 The position of a single thread in a threadgroup

使用以下代码,您还可以根据线程在线程组中的位置以及线程组在网格中的大小和位置来计算线程在网格中的位置:

kernel void 
myKernel(uint2 threadgroup_position_in_grid   [[ threadgroup_position_in_grid ]],
         uint2 thread_position_in_threadgroup [[ thread_position_in_threadgroup ]],
         uint2 threads_per_threadgroup        [[ threads_per_threadgroup ]]) 
{
    
    uint2 thread_position_in_grid = 
        (threadgroup_position_in_grid * threads_per_threadgroup) + 
        thread_position_in_threadgroup;
}

SIMD Groups - SIMD组

线程组中的线程进一步组织成单指令,多数据(SIMD)组,也称为warpswavefronts,它们并发执行。 SIMD组中的线程执行相同的代码。避免编写可能导致内核功能发散的代码;也就是说,遵循不同的代码路径。分歧的典型示例是使用if语句引起的。即使SIMD组中的单个线程采用与其他线程不同的路径,该组中的所有线程也会执行两个分支,并且该组的执行时间是两个分支的执行时间的总和。

线程组到SIMD组的划分由Metal定义。它在内核执行期间,在具有相同启动参数的给定内核的调度之间以及在调度内从一个线程组到另一个线程组保​​持不变。

SIMD组中的线程数由计算管道状态对象的 threadExecutionWidth返回。属性限定符允许您访问线程组中SIMD组的标量索引,以及SIMD组中线程的标量索引:

  • [[simdgroup_index_in_threadgroup]]
    • SIMD组在其线程组中的唯一标量索引,也称为通道ID(lane ID)
  • [[thread_index_in_simdgroup]]
    • SIMD组中线程的唯一标量索引。

虽然线程组可以是多维的,但SIMD组是1D。 因此,SIMD组中线程的位置是所有线程组形状的标量值。 SIMD组大小保持不变,不受线程组大小的影响。

例如,使用图2中所示的相同16 x 16网格,线程执行宽度为16,单个8 x 4线程组由2个SIMD组组成。 因为SIMD组包含16个线程,所以每个SIMD组在线程组中构成2行:

Figure 4 A threadgroup composed of 2 SIMD groups

图5中以红色显示的线程的[[simdgroup_index_in_threadgroup]]值为1,[[thread_index_in_simdgroup]]值为1:

Figure 5 The position of a single thread in a SIMD group

后记

本篇主要讲述了关于线程和线程组,感兴趣的给个赞或者关注~~~

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 200,612评论 5 471
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,345评论 2 377
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 147,625评论 0 332
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,022评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,974评论 5 360
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,227评论 1 277
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,688评论 3 392
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,358评论 0 255
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,490评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,402评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,446评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,126评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,721评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,802评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,013评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,504评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,080评论 2 341

推荐阅读更多精彩内容