cuda-Block和Grid设定

CUDA的Threading:Block和Grid设定

硬件基本架构  实际上在 nVidia 的 GPU 里,最基本的处理单元是所谓的 SP(Streaming Processor),而一颗 nVidia 的 GPU 里,会有非常多的 SP 可以同时做计算;而数个 SP 会在附加一些其他单元,一起组成一个 SM(Streaming Multiprocessor)。几个 SM 则会在组成所谓的 TPC(Texture Processing Clusters)。
  在 G80/G92 的架构下,总共会有 128 个 SP,以 8 个 SP 为一组,组成 16 个 SM,再以两个 SM 为一个 TPC,共分成 8 个 TPC 来运作。而在新一代的 GT200 里,SP 则是增加到 240 个,还是以 8 个 SP 组成一个 SM,但是改成以 3 个 SM 组成一个 TPC,共 10 组 TPC。下面则是提供了两种不同表示方式的示意图。(可参考《NVIDIA G92终极状态!!》、《NVIDIA D10U绘图核心》)
  对应到 CUDA
  而在 CUDA 中,应该是没有 TPC 的那一层架构,而是只要根据 GPU 的 SM、SP 的数量和资源来调整就可以了。
  如果把 CUDA 的 Grid - Block - Thread 架构对应到实际的硬件上的话,会类似对应成 GPU - Streaming Multiprocessor - Streaming Processor;一整个 Grid 会直接丢给 GPU 来执行,而 Block 大致就是对应到 SM,thread 则大致对应到 SP。当然,这个讲法并不是很精确,只是一个简单的比喻而已。
  SM 中的 Warp 和 Block
  CUDA 的 device 实际在执行的时候,会以 Block 为单位,把一个个的 block 分配给 SM 进行运算;而 block 中的 thread,又会以「warp」为单位,把 thread 来做分组计算。目前 CUDA 的 warp 大小都是 32,也就是 32 个 thread 会被群组成一个 warp 来一起执行;同一个 warp 里的 thread,会以不同的数据,执行同样的指令。此外,在 Compute Capability 1.2 的硬件中,还加入了 warp vote 的功能,可以快速的进行 warp 内的简单统计。
  基本上 warp 分组的动作是由 SM 自动进行的,会以连续的方式来做分组。比如说如果有一个 block 里有 128 个 thread 的话,就会被分成四组 warp,第 0-31 个 thread 会是 warp 1、32-63 是 warp 2、64-95 是 warp 3、96-127 是 warp 4。
  而如果 block 里面的 thread 数量不是 32 的倍数,那他会把剩下的 thread 独立成一个 warp;比如说 thread 数目是 66 的话,就会有三个 warp:0-31、32-63、64-65。由于最后一个 warp 里只剩下两个 thread,所以其实在计算时,就相当于浪费了 30 个 thread 的计算能力;这点是在设定 block 中 thread 数量一定要注意的事!
  一个 SM 一次只会执行一个 block 里的一个 warp,但是 SM 不见得会一次就把这个 warp 的所有指令都执行完;当遇到正在执行的 warp 需要等待的时候(例如存取 global memory 就会要等好一段时间),就切换到别的 warp 来继续做运算,藉此避免为了等待而浪费时间。所以理论上效率最好的状况,就是在 SM 中有够多的 warp 可以切换,让在执行的时候,不会有「所有 warp 都要等待」的情形发生;因为当所有的 warp 都要等待时,就会变成 SM 无事可做的状况了~
  下图就是一个 warp 排程的例子。一开始是先执行 thread block 1 的 warp1,而当他执行到第六行指令的时候,因为需要等待,所以就会先切到 thread block 的 warp2 来执行;一直等到存取结束,且刚好有一个 warp 结束时,才继续执行 TB1 warp1 的第七行指令。

                               
登录/注册后可看大图
  实际上,warp 也是 CUDA 中,每一个 SM 执行的最小单位;如果 GPU 有 16 组 SM 的话,也就代表他真正在执行的 thread 数目会是 32*16 个。不过由于 CUDA 是要透过 warp 的切换来隐藏 thread 的延迟、等待,来达到大量平行化的目的,所以会用所谓的 active thread 这个名词来代表一个 SM 里同时可以处理的 thread 数目。
  而在 block 的方面,一个 SM 可以同时处理多个 thread block,当其中有 block 的所有 thread 都处理完后,他就会再去找其他还没处理的 block 来处理。假设有 16 个 SM、64 个 block、每个 SM 可以同时处理三个 block 的话,那一开始执行时,device 就会同时处理 48 个 block;而剩下的 16 个 block 则会等 SM 有处理完 block 后,再进到 SM 中处理,直到所有 block 都处理结束。
  为一个多处理器指定了一个或多个要执行的线程块时,它会将其分成warp块,并由SIMT单元进行调度。将块分割为warp的方法总是相同的,每个warp都包含连续的线程,递增线程索引,第一个warp中包含全局线程过索引0-31。每发出一条指令时,SIMT单元都会选择一个已准备好执行的warp块,并将指令发送到该warp块的活动线程。Warp块每次执行一条通用指令,因此在warp块的全部32个线程执行同一条路径时,可达到最高效率。如果一个warp块的线程通过独立于数据的条件分支而分散,warp块将连续执行所使用的各分支路径,而禁用未在此路径上的线程,完成所有路径时,线程重新汇聚到同一执行路径下,其执行时间为各时间总和。分支仅在warp块内出现,不同的warp块总是独立执行的--无论它们执行的是通用的代码路径还是彼此无关的代码路径。
  建议的数值?
  在 Compute Capability 1.0/1.1 中,每个 SM 最多可以同时管理 768 个 thread(768 active threads)或 8 个 block(8 active blocks);而每一个 warp 的大小,则是 32 个 thread,也就是一个 SM 最多可以有 768 / 32 = 24 个 warp(24 active warps)。到了 Compute Capability 1.2 的话,则是 active warp 则是变为 32,所以 active thread 也增加到 1024。
  在这里,先以 Compute Capability 1.0/1.1 的数字来做计算。根据上面的数据,如果一个 block 里有 128 个 thread 的话,那一个 SM 可以容纳 6 个 block;如果一个 block 有 256 个 thread 的话,那 SM 就只能容纳 3 个 block。不过如果一个 block 只有 64 个 thread 的话,SM 可以容纳的 block 不会是 12 个,而是他本身的数量限制的 8 个。
  因此在 Compute Capability 1.0/1.1 的硬件上,决定 block 大小的时候,最好让里面的 thread 数目是 warp 数量(32)的倍数(可以的话,是 64 的倍数会更好);而在一个 SM 里,最好也要同时存在复数个 block。如果再希望能满足最多 24 个 warp 的情形下,block 里的 thread 数目似乎会是 96(一个 SM 中有 8 个 block)、128(一个 SM 中有 6 个 block)、192(一个 SM 中有 4 个 block)、256(一个 SM 中有 3 个 block) 这些数字了~
  Compute Capability 1.0/1.1 的硬件上,每个grid最多可以允许65535×65535个block。每个block最多可以允许512个thread,但是第三维上的最大值为64。而官方的建议则是一个 block 里至少要有 64 个 thread,192 或 256 个也是通常比较合适的数字(请参考 Programming Guide)。
  但是是否这些数字就是最合适的呢?其实也不尽然。因为实际上,一个 SM 可以允许的 block 数量,还要另外考虑到他所用到 SM 的资源:shared memory、registers 等。在 G80 中,每个 SM 有 16KB 的 shared memory 和 8192 个 register。而在同一个 SM 里的 block 和 thread,则要共享这些资源;如果资源不够多个 block 使用的话,那 CUDA 就会减少 Block 的量,来让资源够用。在这种情形下,也会因此让 SM 的 thread 数量变少,而不到最多的 768 个。
  比如说如果一个 thread 要用到 16 个 register 的话(在 kernel 中宣告的变量),那一个 SM 的 8192 个 register 实际上只能让 512 个 thread 来使用;而如果一个 thread 要用 32 个 register,那一个 SM 就只能有 256 个 thread 了~而 shared memory 由于是 thread block 共享的,因此变成是要看一个 block 要用多少的 shread memory、一个 SM 的 16KB 能分给多少个 block 了。
  所以虽然说当一个 SM 里的 thread 越多时,越能隐藏 latency,但是也会让每个 thread 能使用的资源更少。因此,这点也就是在优化时要做取舍的了。
展开阅读全文

Grid

11-04

Problem Descriptionn  There are n boxes in one line numbered 1 to n, at the beginning, all boxes are black. Two kinds of operations are provided to you:nn1 ai xi :You can choose any xi black boxes in interval [1,ai], and color them white;n2 ai xi :You can choose any xi black boxes in interval [ai,n], and color them white;nn  lcq wants to know if she use these operations in optimal strategy, the maximum number of white boxes she can get, and if she get maximum white boxes, the minimum number of operations she should use.nTips: n1. It is obvious that sometimes you can choose not to use some operations.n2. If the interval of one operation didn’t have enough black boxes, you can’t use this operation.n nnInputn  The first line contains one integer T, indicating the number of test case.n  The first line of each test case contains two integers N (1 <= N <= 1000) and M (1<=M<=1000), indicating that there are N grids and M operations in total. Then M lines followed, each of which contains three integers si(1<=si<=2) , ai and xi (0 <= xi <= N,1<=ai<=N), si indicating the type of this operation, ai and xi indicating that the interval is [1,ai] or [ai,n](depending on si), and you can choose xi black boxes and color them white.n nnOutputn  For each test case, output case number first. Then output two integers, the first one is the maximum boxes she can get, the second one is the minimum operations she should use.n nnSample Inputn1n5 2n2 3 3n1 3 3n nnSample OutputnCase 1: 3 1 问答

没有更多推荐了,返回首页